Свойство коллекции Критерии гибернации (подзапрос?) - PullRequest
2 голосов
/ 28 декабря 2011

Я не очень знаком с Критериями гибернации и прошу прощения, если этот вопрос слишком прост ... Однако, любая помощь очень ценится!

У меня есть две сущности: CD и Track. Каждый CD имеет коллекцию трек-объектов. В каждом треке есть строковое поле с названием «title». Теперь я хочу извлечь, используя Критерии Hibernate, все компакт-диски, имеющие дорожку с установленным значением 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();

Возвращает все компакт-диски независимо от названия дорожки. У кого-нибудь есть предложения?

Заранее спасибо.

Ответы [ 2 ]

9 голосов
/ 28 декабря 2011

Вы очень близки к решению. Вы просто пропустили ограничение, заявив, что дорожка должна быть дорожкой компакт-диска:

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();

или

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);
0 голосов
/ 17 апреля 2012

Вы можете сделать это фактически без объединения - просто используйте cdCriteria.getAlias ​​() вместо строкового значения псевдонима.Таким образом, ключевая строка будет:

trackCriteria.add(Restrictions.propertyEq("trackCd.id", cdCriteria.getAlias() + ".id"));
...