Свойство на колекция от критерии за хибернация (подзаявка?)

Не съм много запознат с критериите за хибернация и се извинявам, ако този въпрос е твърде прост... Въпреки това всяка помощ е много ценена!

Имам два обекта, CD и Track. Всеки компактдиск има колекция от Track-обекти. Във всяка песен има поле за низ, наречено "title". Сега искам да извлека, като използвам Hibernate Criteria, всички компактдискове, които имат песен с "title", зададена на определена стойност. Това, което имам досега, е следното:

//session handling
Criteria cdCriteria = session.createCriteria(CD.class);
DetachedCriteria trackCriteria = DetachedCriteria.forClass(Track.class);
trackCriteria.add(Restrictions.eq("title", "SomeTitle"));
trackCriteria.setProjection(Projections.property("title"));
criteria.add(Subqueries.exists(trackCriteria));
List<CD> cds = criteria.list();

Това връща всички компактдискове, независимо от заглавието на песента. Някой има ли предложения?

Благодаря ви предварително.


person user1119371    schedule 28.12.2011    source източник


Отговори (2)


Вие сте много близо до решението. Току-що пропуснахте ограничението, което гласи, че песента трябва да е песен от компактдиска:

Criteria cdCriteria = session.createCriteria(CD.class, "cd");
DetachedCriteria trackCriteria = DetachedCriteria.forClass(Track.class, "track");
trackCriteria.add(Restrictions.eq("track.title", "SomeTitle"));
trackCriteria.add(Restrictions.propertyEq("track.cd.id", "cd.id"));
trackCriteria.setProjection(Projections.property("track.title"));
criteria.add(Subqueries.exists(trackCriteria));
List<CD> cds = criteria.list();

or

Criteria cdCriteria = session.createCriteria(CD.class, "cd");
DetachedCriteria trackCriteria = DetachedCriteria.forClass(Track.class, "track");
trackCriteria.add(Restrictions.eq("track.title", "SomeTitle"));
trackCriteria.createAlias("track.cd", "trackCd");
trackCriteria.add(Restrictions.propertyEq("trackCd.id", "cd.id"));
trackCriteria.setProjection(Projections.property("track.title"));
criteria.add(Subqueries.exists(trackCriteria));
List<CD> cds = criteria.list();

Можете също така да избегнете подзаявката и просто да използвате съединение

Criteria cdCriteria = session.createCriteria(CD.class, "cd");
criteria.createAlias("cd.tracks", "track");
criteria.add(Restrictions.eq("track.title", "someTitle"));
criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);
person JB Nizet    schedule 28.12.2011
comment
Благодаря ти! Успях да накарам последното ви решение да работи с присъединяването. Другите две се провалят с изключение за картографиране, Unknown entity: null. Вярвам, че това е заради track.cd, тъй като cd не е поле в Track. Връзката е насочена само от CD към Track. Или греша тук? - person user1119371; 28.12.2011
comment
Не, прав си. Предположих, че асоциацията е двупосочна и песента има cd поле. - person JB Nizet; 28.12.2011
comment
Така че е невъзможно да се реши с помощта на подзаявка? Тъй като асоциацията не е двупосочна, единственият начин е чрез използване на съединения? - person user1119371; 28.12.2011
comment
Като се има предвид, че имате нужда от достъп до песните на компактдиска, не виждам как можете да избегнете свързване между компактдиск и песен. - person JB Nizet; 28.12.2011
comment
Има липсваща двойна кавичка в този ред на горния отговор, но StackOverflow не ми позволява да го поправя (минималната дължина за редактиране трябва да бъде 6 знака, очевидно): критерии.createAlias(cd.tracks, track); - person Jeff Evans; 07.05.2013

Можете да направите това всъщност без присъединяването - просто използвайте cdCriteria.getAlias() на мястото на стойността на низа на псевдонима. Следователно ключовият ред ще бъде:

trackCriteria.add(Restrictions.propertyEq("trackCd.id", cdCriteria.getAlias() + ".id"));
person Y G    schedule 17.04.2012
comment
Това използва вътрешния псевдоним на хибернация, а не дефиниран от потребителя. - person Y G; 17.04.2012