CABA 5.9 представление заставляет выгружать в память всю таблицу

Здравствуйте!

Я создаю браузер сущностей Счет

И вместо того, чтобы работать как ожидается
лог запросов показывает, что сначала делается запрос,
который забирает данные о первых 500 счетах (в нем не приджойнина таблица PAYMENTS),
а потом выгружает ВСЕ платежи из базы данных, в моем случае это 51.000 строк
и уже в памяти собирает в соответствии с view.

Есть сущность счета

@PrimaryKeyJoinColumn(name = "CARD_ID", referencedColumnName = "ID")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorValue("1")
@Table(name = "BILLS")
@Entity(name = "project$Bill")
@EnableRestore
@TrackEditScreenHistory
public class Bill extends TsCard {
    private static final long serialVersionUID = -8609845511407838736L;

    @Column(name = "NUMBER_", length = 50)
    protected String number;

    @Column(name = "STATUS", length = 50)
    protected String status;

    @Composition
    @OnDelete(DeletePolicy.DENY)
    @OneToMany(mappedBy = "bill", fetch = FetchType.LAZY)
    protected List<Payment> payments;
	
	...
	get...
	set...
}

Вложенная коллекция платежей по счету
payments

Сущность платежа

@PrimaryKeyJoinColumn(name = "CARD_ID", referencedColumnName = "ID")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorValue("2")
@Table(name = "PAYMENTS")
@Entity(name = "project$Payment")
@EnableRestore
@TrackEditScreenHistory
public class Payment extends TsCard {
    private static final long serialVersionUID = -482698773261271605L;

    @Column(name = "NUMBER_", length = 50)
    protected String number;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "BILL_ID")
    protected Bill bill;
	
	...
	get ...
	set ...
}

Представление, которое должно выгружать счет с коллекцией платежей одним запросом

<view class="company.name.thesis.Bill"
          extends="_local"
          name="browseExtended">
      <property name="payments"
                      view="_local"/>
</view>

Запрос, который выгружает всю таблицу
SELECT t0.CARD_ID, t3.ID, t3.CARD_TYPE, t3.VERSION, t3.CREATE_TS,
t3.CREATED_BY, t3.CATEGORY_ID, t3.CREATOR_ID, t3.DELETE_TS,
t3.DELETED_BY, t3.DESCRIPTION, t3.HAS_ATTACHMENTS, t3.HAS_ATTRIBUTES,
t3.JBPM_PROCESS_ID, t3.PARENT_CARD_ID, t3.PARENT_CARD_ACCESS,
t3.PROC_ID, t3.STATE, t3.SUBSTITUTED_CREATOR_ID, t3.UPDATE_TS,
t3.UPDATED_BY, t3.SIGNATURES, t2.AMOUNT, t2.BILL_ID, t2.PAYMENT_DATE,
t2.NUMBER_, t2.STATUS
FROM dbo.BILLS t0
INNER JOIN dbo.WF_CARD t1 ON t0.CARD_ID = t1.ID
INNER JOIN dbo.PAYMENTS t2 ON t0.CARD_ID = t2.BILL_ID
INNER JOIN dbo.WF_CARD t3 ON t2.CARD_ID = t3.ID
WHERE (t1.DELETE_TS IS NULL) AND t1.CARD_TYPE = 1 AND t3.DELETE_TS IS NULL
ORDER BY t0.CARD_ID ASC

Если из view убрать поле payments, то всё проходит.

CUBA 5.9
База MSSQL 13
количество счетов в БД = 49500
количество платежей в БД = 51537

Похоже, что фрэймворк сам принимает решение, что в данной ситуации надо сделать именно так

Добрый день,
Это особенность OpenJPA - библиотеки ORM, используемого в данной версии платформы. Иногда библиотека действительно принимает такие странные решения.
Известен способ обхода проблемы - добавить в определении view для свойства payments атрибут lazy="true", вроде бы так.

Спасибо за ответ!

Уже обошел эту проблему обновлением пары библиотек.
В том числе переходом с CUBA 5.9.6 на 5.9.13

Жаль, что нет возможности проверить.

То есть недостаточно написать в сущности @ManyToOne(fetch = FetchType.LAZY)
нужно еще раз явно указать это во view?

Это разные вещи.
В сущности - если вы так не напишете, то связь будет грузиться вообще всегда без вашего желания.

А во view - мы определяем для ORM инструкцию, сколько данных и как загружать в данном конкретном случае.