Подзапросы Критерии HIbernate И прогнозы для объединенных таблиц - PullRequest
0 голосов
/ 29 апреля 2020

Создание Java веб-приложения с использованием Hibernate 5.4.10. Наконец, как ORM

У меня есть страница, для которой мне нужно запросить все мои объекты Contract. Каждый Контракт имеет серию (некоторую случайную строку), и для этого списка я хочу, чтобы последний контракт был заключен только на серию (как определено в поле «создан» в базе данных). Как вишня сверху, каждый Контракт связан с объектом Компании и сортируется по его имени

@Entity
@Table(name = "contract")
public class Contract {

   String series;

   @Temporal(TemporalType.TIMESTAMP)
   Date created;

   @ManyToOne()
   @JoinColumn(name = "company_id")
   Company company;


   @OneToMany(mappedBy = "parentContract", fetch = FetchType.EAGER)
   Set<ContractDetails> details;

   ...

enter image description here

Так что, если я запросил этот пример таблицы Я бы ожидал получить два контракта (2 и 3 имеют одинаковую серию ZZZZZ и, таким образом, возвращается только созданный позже), упорядоченный как 3 -> 1 (поскольку компания 1 называется "Альфа" и company 2 "Bravo" )

Каждый объект Contract имеет набор объектов ContractDetails (которые я также хочу показать), которые, в свою очередь, имеют несколько объектов Foo (которые я не хочу показать!)

@Entity
@Table(name="contract_details")
public class ContractDetails {

    @ManyToOne
    @JoinColumn(name="contract_id")
    @XmlTransient
    Contract parentContract;

    String bar;

    @OneToMany(mappedBy="parentDetails", fetch=FetchType.EAGER)
    Set<Foo> foos = new HashSet<>();

В его нынешнем виде я использовал собственный запрос SQL для извлечения этого списка контрактов:

    String sql = "SELECT contract.* FROM contract " + 
            "INNER JOIN (SELECT series AS s, MAX(created) AS maxtime FROM contract GROUP BY series) latest " + 
            "ON contract.series = latest.s AND contract.created = latest.maxtime " + 
            "INNER JOIN company " + 
            "ON contract.company_id = company.id " + 
            "ORDER BY company.name, contract.created";

    List<Contract> result = session.createNativeQuery(sql, Contract.class).list();

верные данные верны. Однако это происходит медленно, потому что все объекты Foo для каждого отдельного объекта ContractDetail также выбираются.

Итак, я ищу какой-то способ выполнения этих критериев (выборка только последнего Контракта для каждой серии, отсортированный по названию компании) И чтобы Hibernate НЕ извлекал поле foos на объектах ContractDetails.

Я понимаю, что этого можно достичь с помощью запросов Критерии и Прогнозы * 1033 Hibernate * но я не совсем взломал код, как объединить их с агрегацией по группам ...


Q: Не могли бы вы просто лениво загрузить foos?

A: Джексон, продюсер JSON, выдаст ошибку при попытке сериализации моего списка контрактов - и хотя я знаю, что есть способы заставить Джексона лучше сотрудничать с Hibernate, есть и тот факт, что я не хочу для загрузки поля foos вообще в этом случае они не нужны


Q: Не могли бы вы создать урезанный класс ContractDetails без * 104 4 * поле, которое будет использоваться только для этой страницы?

A: Это одна возможность, мне просто интересно, возможно ли это без введения дополнительных, довольно избыточных классов моделей.

...