Сумма Joda Money разделена на 2 столбца с помощью Spring Data JPA
Я пытаюсь использовать денежный класс JODA с типами Jadira для обработки отображения в Hibernate 4.
Это работает хорошо (за исключением того, что я получаю слишком много валютных полей).
Но мне нужно создать агрегированный запрос для суммирования некоторых итогов.
Это объявление типа.
@Columns(columns = { @Column(name = "total_currency", length=10), @Column(name = "total") })
@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency")
private Money total;
И я пытаюсь определить запрос, что-то вроде:
@Query(value="select sum(oi.total) from OrderItem oi where oi.order = ?1")
Double calculateSubtotal(Order order);
Есть ли способ агрегировать запрос к полю Money, используя JPQL?
Благодарю.
1 ответ
Есть два способа, но они ограничены, и я сомневаюсь, что они вам действительно понравятся:(Основное ограничение состоит в том, что в Hibernate HQL вы не можете вызывать методы, если они не являются сопоставленными свойствами - конец истории. Hibernate не поддерживает вызов метода
С другой стороны, вы можете отображать один столбец столько раз, сколько хотите, если вы помните, что только одно сопоставление может быть обновляемым. Имея это в виду, первый шаг заключается в том, что вам нужно, чтобы Hibernate осознавал деньги joda. Очевидно, вы не можете просто аннотировать это. Есть два способа сделать это:
Вы можете использовать XML, чтобы фактически аннотировать класс Money как класс @Embeddable. Конфигурация XML в спящем режиме может использоваться для настройки чего-либо с закрытым исходным кодом. Из того, что я вижу в Деньгах йода - конфигурация времени.
Второе решение. Вероятно, тот, который я бы использовал. Оборачивает класс Money в оболочку, объявленную как @Embeddable. Эта встроенная оболочка позволяет вам определить несколько отображений для существующих столбцов базы данных. Когда вы устанавливаете значение в WRAPER, это значение будет добавлено во время содовой, которое находится внутри.
После того, как вы это сделаете, вы можете выставить через обертку любой атрибут класса Money, который вы хотите, и выполнить любое агрегирование.
@Embeddable
public class MoneyWrapper {
@Columns(columns = { @Column(name = "total_currency", length=10), @Column(name = "total") })
@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency")
Money totalmoney;
@Column(name = "total",updateable=false,insterable=false);
BigDecimal total to agregate;
@Column(name = "total_currency",updateable=false,insterable=false);
BigDecimal totalCurrency;
}
В результате этого сопоставления вы можете сделать запрос как:
@Query (value = "выберите сумму выбора (oi.total.totalCurrency) из OrderItem oi, где oi.order =?1")