Hibernate HQL: преобразование оператора SQL в HQL (с помощью подвыборов / объединений) - PullRequest
3 голосов
/ 18 сентября 2009

Я был бы очень признателен за помощь в преобразовании следующего оператора SQL в действительный оператор HQL. Я пытался часами, но безуспешно:

SELECT * FROM master as m left outer join (select * from child as c where c.id = (select max(d.id) from child as d where d.MasterFk = c.MasterFk) )as b ON m.id = b.MasterFk;


public class Master {
 private Long id;
 private Collection childs;
 ...
}

public Class Child {
  private Long id;
  private Master master;
}

В файле отображения Hibernate я сопоставляю мастера с ребенком с помощью стандартного набора (-Mapping), и отношение «ребенок-мастер» является ассоциацией «многие к одному». (Это работает.)

==> Целью является запрос мастера только с самой последней дочерней записью (= только одна запись!), Правильно инициализированной как единственный элемент в наборе дочерних элементов ...

Что бы я ни пытался, я с треском провалился.

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 18 сентября 2009

Я не уверен, что вы можете сделать это. Проблема, которую я вижу, не в запросе, а в инициализации. Если вы не вернете все объекты для набора, то я не уверен, что Hibernate сможет инициализировать набор.

В логике Hibernate, если объект (здесь, Set) предоставляется (не NULL, не прокси) в графе объектов, то он должен быть завершен. Набор, содержащий только один элемент и, следовательно, не может загружать другие, поскольку он не является прокси-сервером, находится вне логики Hibernate . В логике Hibernate набор является либо нулевым, либо прокси-сервером, либо полностью загруженным ( за исключением сложных случаев для огромных коллекций, где они загружаются пакетами ... ).

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

Я предлагаю две альтернативы:

1. Создать объект в Java

Альтернативой является запрос данных, которые вы хотите, а затем заполнение ваших объектов в вашем конкретном коде Java.

Запрос может быть намного проще, например:

    SELECT m.id, max(c.id) 
    FROM master as m 
    left join m.childs as c 
    group by m.id

Java-код будет создавать то, что вы хотите от этого List<Object[]> результата.

Или вы могли бы дать Мастеру соответствующий конструктор и использовать новый (возвращающий List<Master>):

    SELECT new Master(m.id, max(c.id)) 
    FROM master as m 
    left join m.childs as c 
    group by m.id

2. Добавить участника

У вас также может быть член lastChild на Мастере. Можно указать отображение, чтобы загрузить его именно так, как вам нужно.

Я предлагаю формулу, которая имеет преимущество только для чтения. Помните, что формулы принимают SQL, а не HQL. Вставьте SQL, соответствующий вашему подзапросу.

0 голосов
/ 18 сентября 2009

Зачем конвертировать - используйте собственный SQL и Hibernate Transformers .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...