2011-12-28 85 views
2

我对Hibernate Criteria不是很熟悉,如果这个问题太简单了,我表示歉意......但是,非常感谢任何帮助!Hibernate Criteria集合属性(子查询?)

我有两个实体,CD和Track。每张CD都有音轨对象的集合。在每个轨道中都有一个名为“title”的字符串字段。现在我想要使用Hibernate Criteria检索所有具有“title”设置为特定值的Track的CD。我到目前为止是这样的:

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

这将返回所有的CD,无论曲目标题的。有人有任何建议吗?

预先感谢您。

回答

9

您非常接近解决方案。你只是错过了限制,说明比轨道必须是CD的曲目:

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

谢谢!我设法让你的最后一个解决方案工作,加入。另外两个映射异常失败,Unknown entity:null我相信这是因为“track.cd”,因为“cd”不是Track中的字段。仅从CD到Track的关系是定向的。还是我在这里错了? – user1119371 2011-12-28 15:28:45

+0

不,你说得对。我认为该协会是双向的,并且一个赛道有一个CD场。 – 2011-12-28 15:32:23

+0

那么,通过使用子查询是不可能的?由于关联不是双向的,唯一的方法是使用连接? – user1119371 2011-12-28 15:56:43

0

您可以在没有连接的情况下实际执行此操作 - 只需使用alias的字符串值的cdCriteria.getAlias()位置即可。因此,关键线将是:

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

这使用hibernate内部别名,而不是用户定义的别名。 – 2012-04-17 17:55:51