[Hibernate] можно ли написать такой запрос на HQL?

6yrop

Можно ли на HQL аналог вот такого SQL-ного запроса?
select T1.*
from T1 left outer join T2
on T1.a = T2.a and T2.b = 'test'

6yrop

вот вам объектно-ориентированный язык запросов

katrin2201

Вообще, я не спец в HQL, но мне казалось, что сам хибернейт был придуман для того, чтобы этих джойнов избежать.
Что мешает в классе, объекты которого у тебя хранятся в T2, сделать Collection из объектов T1, задав правильный foreign key в соотв *.hbm.xml файле?
В этом случае ты выбираешь просто все объекты из T2, какие нужны, а потом уже объектно-ориентированно бродишь по объектам из T1. И хибернейт _сама_ подгрузит нужный Collection из БД без всяких телодвижений с твоей стороны.
А если тебе вынь да положь именно джойн - не поленился бы залезть в гугл и тогда первой же ссылкой ты бы прочитал.
Удачи! =)

Hastya

есть по крайней мере 10 способов это сделать.
самый тупой:
 from T1 as t1  left outer join t1.t2 as t2
where t2.b = 'test'

rosali

Это разные запросы. Иди ботай join.

Hastya

иди ботай HQL.

rosali

Да при чем тут HQL? Написав where ты полностью потеряешь случаи, где t2.b != 'test', а исходный запрос подразумевает, что они останутся, просто будут иметь на месте t2.b null. Или действительно я туплю? Просто нет сейчас под рукой SQL-ной консоли...

zya369

имхо, чтобы вместо test было Null, его надо в условия join'а запихать
а если t2.b = 'test' поставить в where , то это условие будет провряться уже на результате join'а и никаких null'ов не получится

rosali

ну дык. Вот запрос из первого поста
select T1.* from T1 left outer join T2 on T1.a = T2.a and T2.b = 'test' 

Хмм, T1.*... А что тогда вообще дает этот "and T2.b = 'test'"?

zya369

кстати да, нах там там вторая таблица с outer join'ом - непонятно

Hastya

а исходный запрос подразумевает, что они останутся,
Неа, в исходном тоже не пойми что. Смысл исходного запроса я не понимаю, но тут уж "каков вопрос"...

Andr163

выдать записи из т1, у которых атрибут а равен атрибуту а записей из т2 с полем b равным 'test'

rosali

не-не, если дописать t2.*, то для каждой строчки из t1 будет искаться подходящая строчка из t2, и если не нашлась, то t2.* будет забиваться null-ами, а когда t2.b='test' уносишь в where, то такие строчки будут просто теряться. Чуть ближе к истине
 ... where t2.b = 'test' or t2.b is null 

но в t2 могут быть свои null-ы изначально...

Hastya

поскольку для некоторых записей t2 = null, то условие t2.b = 'test' для них выполняться не будет, соответственно любые пустые записи из левого джойна будут отфильтрованы, тогда зачем outer join?

6yrop

Хмм, T1.*... А что тогда вообще дает этот "and T2.b = 'test'"?
вот более осмысленный пример

select T1.*from T1 left outer join T2 on T1.a = T2.a and T2.b = 'test'
order by T2.c

6yrop

code:-------------------------------------------------------------------------------- ... where t2.b = 'test' or t2.b is null --------------------------------------------------------------------------------
но в t2 могут быть свои null-ы изначально...
даже если в T2 нет своих налов все равно это не тоже самое, могу привести пример на конкретных данных

rosali

Приводи. А то я часто в join-ах путаюсь, будем образовываться

6yrop

rosali

О! оказывается
join on ... and T1.b = 'test'

Ладно, тогда будем дальше думать...

6yrop

ой, небольшая опечатка.
Вот как в первом посте

rosali

Так вот и непонятно в чем смысл первого пример, он всегда возвращает select * from T1, или нет?Повторы в T2.a что ли могут сказываться?

6yrop

Вот пример, где может понадобиться такой запрос.

Выдать все виды вклада, отсортированные по процентной ставке годовых (срок = 12). Причем у некоторых вкладов нет срока равного 12 месяцев.
Как это выразить на HibernateQL, я не нашел, потому что там нельзя
1. писать в join-е on
2. делать outer join с результатом запроса (подзапроса)

6yrop

он всегда возвращает select * from T1
это был не полный пример, в реальных примерах на поля таблицы T2 можно накладывать условия или сортировать по ним
Повторы в T2.a что ли могут сказываться?
в общем случае да

6yrop

но мне казалось, что сам хибернейт был придуман для того, чтобы этих джойнов избежать.
Hibernate был придуман фанатами Java, которые не понимают красоту реляционной теории. Зачем они это сделали известно только им.

rosali

Причем у некоторых вкладов нет срока равного 12 месяцев.
То есть у них тогда процентная ставка будет null, так и надо? Составь просто union и не парься, отдельно те, где есть 12 месяцев, отдельно где нет. Для вторых еще по идее не плохо бы процентную ставку саппроксимировать...

Hastya

Как это выразить на HibernateQL, я не нашел, потому что там нельзя
1. писать в join-е on
2. делать outer join с результатом запроса (подзапроса)
Потому что в Hibernate нет join-ов. Ключевое слово join в HQL придумано для удобства. То, что ты написал, удобнее делать через коллекции и фильтры, а может быть через критерии.

xz_post

не по теме ...
у кого нибудь есть дистрибутив NHibernate для дотнета ? расшарьте пожалуйста...

bansek

блин! до чего же ббкоды кривые! никакими способами не смог сделать линк на ресурс, когда в пути был пробел =\

6yrop

То есть у них тогда процентная ставка будет null, так и надо?
да
Составь просто union и не парься, отдельно те, где есть 12 месяцев, отдельно где нет.
в HQL есть union? я не нашел.
просто union
попробуй запиши запрос с union. Читабильность такого запроса явно будет хуже. Выполняться он будет значительно медленнее.

6yrop

Hibernate для дотнета, нафиг не нужен. Там есть простые и мощные DataSet-ы.

bansek

сложные и дохлые

katrin2201

Звиняюсь за некрофильство, но просто в очередной раз копался в мануале хибернейта и увидел следующее.
Может на HQL написать такое и нельзя, но
1. Есть subselect - пишешь для класса произвольный SQL запрос. Не уверен, правда, что там джойны можно писать, не проверял. Зато там можно вставлять различные count итд.
2. Есть Criteria Queries. С помощью них почти наверняка можно выразить то, что ты хочешь.
Пример из мануала.

List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.createCriteria("kittens")
.add( Restrictions.like("name", "F%")
.list;

ЗЫ Это все взято из доки по Hibernate 3.0

6yrop

С помощью них почти наверняка можно выразить то, что ты хочешь.
вообще, тред начался с вопроса как это сделать? Вопрос был сформулирован четко. Напиши запрос, а не строй предположения.

katrin2201

Хоть твой вопрос отвечен и не четко, зато, если кому надо будет, он будет знать куда копать. Других целей я перед собой не ставил.
ЗЫ Возможно попозжее и напишу.
ЗЗЫ. С subselect например делаешь так

<class name="">
<subselect>
твой SQL запрос из первого поста
</subselect>
...
</class>

Правда, эта ерундень будет рид-онли.

6yrop

зато, если кому надо будет, он будет знать куда копать
типа надо документацию Hibernate-а посмотреть?

6yrop

на HQL!

katrin2201

Типо того =)
Типа меня ломает. В критериях есть сортировка по произвольному елементу. Ставишь ее.
Думаю там где нуллы оно само учтет.
По второму вопросу - я в своем некрофильском посте сказал - что на HQL такое нельзя.
ЗЫ Хибернейт вообще, как я понимаю, от HQL уходить пытается. Поэтому рассматривать его как удобное самодостаточное средство для получения всего и вся я бы не стал =)

6yrop

HQL уходить пытается
напиши плиз ссылку где об этом пишут.
Поэтому рассматривать его как удобное самодостаточное средство для получения всего и вся я бы не стал
а чем они его заменить хотят?
в документации о HQL больше всего написано, чем о других способах выборки

katrin2201

Про уходить пытается - скорее мое дичное мнение. Линк не вспомню.
Заменить - Criteria Queries.
http://www.hibernate.org/hib_docs/v3/reference/en/html/
Там и пишут.
Оставить комментарий
Имя или ник:
Комментарий: