Сумма 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. Очевидно, вы не можете просто аннотировать это. Есть два способа сделать это:

  1. Вы можете использовать XML, чтобы фактически аннотировать класс Money как класс @Embeddable. Конфигурация XML в спящем режиме может использоваться для настройки чего-либо с закрытым исходным кодом. Из того, что я вижу в Деньгах йода - конфигурация времени.

  2. Второе решение. Вероятно, тот, который я бы использовал. Оборачивает класс 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")

Другие вопросы по тегам