|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 8:01 |
|
|
Всем привет.
Имеем сущность юзер. И 3 ссылающиеся на него таблички
| Код: |
Class User{
........
}
Class userChild1{
.....
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
.....
}
Class userChild2{
.....
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
.....
}
Class userChild3{
.....
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
.....
}
|
Нужно одним запросом выбрать юзера и 3 сущности указывающие на него.
Sql запрос выглядит так:
| Код: |
SELECT ..... from user
inner join userChild1 child1 ON child1.user_id=user.id
inner join userChild2 child2 ON child2.user_id=user.id
inner join userChild3 child3 ON child3.user_id=user.id
where ......
|
Как это сделать hql запросом никак не могу понять, может кто подскажет?
ТО что смог сделать:
| Код: |
from user user inner join userChild1 child1 where....
|
Вываливает такой эксешн:
| Код: |
org.hibernate.hql.ast.QuerySyntaxException: Path expected for join! [from User user inner join childUser1 child1 where user.id = 2]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:263)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
|
_________________ http://LinguaLeo.ru/r/8b3o08 |
|
|
|
 |
Староверъ : 7629 Ктапубеп Откуда: Elfland
|
Янв 26, 2012 8:51 |
|
|
|
|
|
|
 |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 8:59 |
|
|
Не ну hql запрос то я сделал в итоге, но меня напрягает то что в итоговом sql запросе присутствуют cross join.
В общем как получается, если мы имеем несколько сущностей которые ссылаются на одну и ту же сущность и отношение у них ManyToOne, и нам нужно получить все эти сущности, то hql запрос получается извратный и sql тоже вырисовывается более сложный чем должен быть по идее.
Думал как можно использовать left-ы и прочие join-ы, картина получается та же.
А вот если у нас будет отношение OneToMany (то есть наоборот главная сущность будет иметь список потомков), то запросы выглядят намного красивее.
Только я никак не пойму почему _________________ http://LinguaLeo.ru/r/8b3o08 |
|
|
|
 |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 9:03 |
|
|
| Староверъ писал(а): |
| Код: |
| from User u join u.child1 where... |
Плюс у хиба опять же не один тип join'ов. |
О мудрый Стас скажи мне, что ты имел ввиду  _________________ http://LinguaLeo.ru/r/8b3o08 |
|
|
|
 |
WebPrj : 72 Новичок
|
Янв 26, 2012 9:21 |
|
|
| nullvoid писал(а): |
А вот если у нас будет отношение OneToMany (то есть наоборот главная сущность будет иметь список потомков), то запросы выглядят намного красивее.
Только я никак не пойму почему |
ну дак это жизненнее ситуация:
Родитель ---> дети
Что по ООП, что ОРМ-навигации-связям. |
|
|
|
 |
Староверъ : 7629 Ктапубеп Откуда: Elfland
|
Янв 26, 2012 9:25 |
|
|
| Код: |
| from User u join u.child1 where... |
Так че тут извратного? По-мому достаточно понятно выходит, ну будет у тебя еще join u.child2 join u.child3, ну ивсе вроде.. Результирующий запрос конечно может быть не элегантен, но Хибу нелегко сказать "измени такой-то запрос вот так-то", у него достаточно умеренный набор атрибутов для этого.
А что, кстати, не нравится в запросах-то? Ты ж без join'a не можешь тут, верно?
И да.. если у тебя в связи OTO не указано contstraint="true" (что значит, что связь обязательна, всегда у родительского объекта будет дочерний), то ты просто не в состоянии сделать ленивую загрузку, дочерний объект будет всегда загрузаться, так что в таком случае join'ы не нужны вовсе. _________________ JTalks Open Source Project, JT Webinars, JT Interview |
|
|
|
 |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 9:28 |
|
|
Ок!
Есть папа и есть у него дети - 3 негритенка, 2 японка, 4 бегимотика у которых не болят животики
Ситуэйшн адын:
Папа знает про всех своих детей, и мы можем выполнить запрос без лишних наворотов - всё ок
Ситуэйшн ы:
Папа не знает про своих детей (ему повезло ) а дети знают про папу.
Технически в базе что в первом что во втором случае будут одни и те же связи, то есть дочерние таблицы будут иметь внешний ключ на родителя.
И sql запрос один и тот же. Дык почему хибер строит запрос во втором случае с наворотами?
Вернее вопрос такой: какова хрена они убрали ON из hql когда мы делаем join - ведь ситуации в жизни бывают разные. _________________ http://LinguaLeo.ru/r/8b3o08 |
|
|
|
 |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 9:36 |
|
|
| Староверъ писал(а): |
| Код: |
| from User u join u.child1 where... |
Так че тут извратного? По-мому достаточно понятно выходит, ну будет у тебя еще join u.child2 join u.child3, ну ивсе вроде.. Результирующий запрос конечно может быть не элегантен, но Хибу нелегко сказать "измени такой-то запрос вот так-то", у него достаточно умеренный набор атрибутов для этого.
А что, кстати, не нравится в запросах-то? Ты ж без join'a не можешь тут, верно?
И да.. если у тебя в связи OTO не указано contstraint="true" (что значит, что связь обязательна, всегда у родительского объекта будет дочерний), то ты просто не в состоянии сделать ленивую загрузку, дочерний объект будет всегда загрузаться, так что в таком случае join'ы не нужны вовсе. |
В том то и проблема, что мне на ровном месте пришлось так извратиться:
| Код: |
select distinct user1, child1, child2, child3 from ChildUser1 child1, ChildUser2 child2, ChildUser3 child3
join child1.user user1
join child2.user user2
join child3.user user3
where user1.id = 2
|
Потому что тут join работает в одну сторону - в сторону OneToMany, а когда у нас связь многие к одному, то хибер помимо inner join ещё и cross делает на каждую связь с юзером _________________ http://LinguaLeo.ru/r/8b3o08 |
|
|
|
 |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 9:45 |
|
|
| Староверъ писал(а): |
| join u.child2 join u.child3 |
Это когда связь один ко многим, а когда связь многие к одному, этих свойств (child2, child3) у юзера нет _________________ http://LinguaLeo.ru/r/8b3o08 |
|
|
|
 |
WebPrj : 72 Новичок
|
Янв 26, 2012 9:46 |
|
|
| nullvoid писал(а): |
Ситуэйшн адын:
Папа знает про всех своих детей, и мы можем выполнить запрос без лишних наворотов - всё ок
Ситуэйшн ы:
Папа не знает про своих детей (ему повезло ) а дети знают про папу.
Технически в базе что в первом что во втором случае будут одни и те же связи, то есть дочерние таблицы будут иметь внешний ключ на родителя.
|
нет
в 1 случает будет каскад и декларативная связь - констрейнт
во 2 будет FK без каскада, т.к. родители - справочник
Это при проектировании ОТ РСУБД.
Что там херачит ОРМ надо посмотреть |
|
|
|
 |
Староверъ : 7629 Ктапубеп Откуда: Elfland
|
Янв 26, 2012 10:12 |
|
|
Ну это если честно достаточно странный запрос Особенно не ясно почему child - это то, что снаружи.. Кстати, ты уверен, что это должен быть один запрос, а не три?
А можешь его привести прям как есть в коде? Может станут понятными твои намерения.
Если нужно выбрать родителя по ребенку, то:
| Код: |
| from Parent where p.child=:childId |
_________________ JTalks Open Source Project, JT Webinars, JT Interview |
|
|
|
 |
nullvoid : 505 Постоянный посетитель Откуда: Красноярск
|
Янв 26, 2012 10:14 |
|
|
|
|
|
|
 |
|
|
|