Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

HQL и join-ы
Список форумов
 ->  Персистентность в Java (JPA, ORM, ODB)


 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
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
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеЯнв 26, 2012 8:51 
Ответить с цитатой
Код:
from User u join u.child1 where...
Плюс у хиба опять же не один тип join'ов.
_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
nullvoid : 505
Постоянный посетитель
Откуда: Красноярск

СообщениеЯнв 26, 2012 8:59 
Ответить с цитатой
Не ну hql запрос то я сделал в итоге, но меня напрягает то что в итоговом sql запросе присутствуют cross join.
В общем как получается, если мы имеем несколько сущностей которые ссылаются на одну и ту же сущность и отношение у них ManyToOne, и нам нужно получить все эти сущности, то hql запрос получается извратный и sql тоже вырисовывается более сложный чем должен быть по идее.
Думал как можно использовать left-ы и прочие join-ы, картина получается та же.
А вот если у нас будет отношение OneToMany (то есть наоборот главная сущность будет иметь список потомков), то запросы выглядят намного красивее.
Только я никак не пойму почему
_________________
http://LinguaLeo.ru/r/8b3o08
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
nullvoid : 505
Постоянный посетитель
Откуда: Красноярск

СообщениеЯнв 26, 2012 9:03 
Ответить с цитатой
Староверъ писал(а):
Код:
from User u join u.child1 where...
Плюс у хиба опять же не один тип join'ов.

О мудрый Стас Embarassed скажи мне, что ты имел ввиду Very Happy
_________________
http://LinguaLeo.ru/r/8b3o08
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
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
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
nullvoid : 505
Постоянный посетитель
Откуда: Красноярск

СообщениеЯнв 26, 2012 9:28 
Ответить с цитатой
Ок!
Есть папа и есть у него дети - 3 негритенка, 2 японка, 4 бегимотика у которых не болят животики Very Happy

Ситуэйшн адын:
Папа знает про всех своих детей, и мы можем выполнить запрос без лишних наворотов - всё ок

Ситуэйшн ы:
Папа не знает про своих детей (ему повезло Very Happy ) а дети знают про папу.

Технически в базе что в первом что во втором случае будут одни и те же связи, то есть дочерние таблицы будут иметь внешний ключ на родителя.
И sql запрос один и тот же. Дык почему хибер строит запрос во втором случае с наворотами?

Вернее вопрос такой: какова хрена они убрали ON из hql когда мы делаем join - ведь ситуации в жизни бывают разные.
_________________
http://LinguaLeo.ru/r/8b3o08
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
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
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
nullvoid : 505
Постоянный посетитель
Откуда: Красноярск

СообщениеЯнв 26, 2012 9:45 
Ответить с цитатой
Староверъ писал(а):
join u.child2 join u.child3

Это когда связь один ко многим, а когда связь многие к одному, этих свойств (child2, child3) у юзера нет
_________________
http://LinguaLeo.ru/r/8b3o08
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
WebPrj : 72
Новичок

СообщениеЯнв 26, 2012 9:46 
Ответить с цитатой
nullvoid писал(а):

Ситуэйшн адын:
Папа знает про всех своих детей, и мы можем выполнить запрос без лишних наворотов - всё ок

Ситуэйшн ы:
Папа не знает про своих детей (ему повезло Very Happy ) а дети знают про папу.

Технически в базе что в первом что во втором случае будут одни и те же связи, то есть дочерние таблицы будут иметь внешний ключ на родителя.

нет
в 1 случает будет каскад и декларативная связь - констрейнт
во 2 будет FK без каскада, т.к. родители - справочник
Это при проектировании ОТ РСУБД.
Что там херачит ОРМ надо посмотреть
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Староверъ : 7629
Ктапубеп
Откуда: Elfland

СообщениеЯнв 26, 2012 10:12 
Ответить с цитатой
Ну это если честно достаточно странный запрос Smile Особенно не ясно почему child - это то, что снаружи.. Кстати, ты уверен, что это должен быть один запрос, а не три?
А можешь его привести прям как есть в коде? Может станут понятными твои намерения.
Если нужно выбрать родителя по ребенку, то:
Код:
from Parent where p.child=:childId

_________________
JTalks Open Source Project, JT Webinars, JT Interview
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail
nullvoid : 505
Постоянный посетитель
Откуда: Красноярск

СообщениеЯнв 26, 2012 10:14 
Ответить с цитатой
Да ладно, всё ок, в принципе я ответы на свои вопросы получил. Так что спасибо Smile
_________________
http://LinguaLeo.ru/r/8b3o08
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора ICQ Number
 
Начать новую тему  Ответить на тему
Страница 1 из 1
Список форумов
 -> Персистентность в Java (JPA, ORM, ODB)


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru