我想使用与另一个实体的连接在实体上运行条件查询。但是从Java / Hibernate的角度来看,没有对第二个实体的引用,只有一个从第二个到第一个实体。
为了使其易于理解,以下是猫的情况:
===== Cat.java =====
@Id private long id;
@Column( unique = true, nullable = false )
private String name;
===== Kitten.java =====
@Id private long id;
@Column( unique = true, nullable = false )
private String name;
@OneToOne(optional = false)
private Cat mother; //only one child per mother ...
现在我想查询带限制的猫和Kitten的OrderBy。
session.createCriteria(Cat.class)
.createAlias(???? , "kitten")
.add( Restrictions.like( "kitten.name", "name_of_a_kitten" )
.addOrder( Order.asc( "kitten.name" ) )
.list();
首先我想过使用子查询,但我找不到订购的解决方案,而且subquerys不像我眼中的别名一样可读。
猫不能改变,因此无法改变双向性。
我如何实现查询?
顺便说一下。我正在使用hibernate 4.2。
答案 0 :(得分:0)
我认为通过简单的hibernate条件查询无法实现您的要求。
标准API可以选择"只有root实体,您需要Cat作为根实体。不幸的是,Cat实体没有引用Kitten,因此无法加入它。
从我的角度来看,你只有两个选择:
1)HQL
如果你没有固定到标准api,只需使用hql。
final List<Cat> cats = session.createQuery("select c from Kitten k join k.mother c where k.name=:name order by k.name")
.setParameter("name", "name_of_a_kitten").list();
2)明确从小猫集合中提取猫
选择小猫收集
final List<Kitten> kittens = session.createCriteria(Kitten.class)
.add(Restrictions.like("name", "name_of_a_kitten"))
.addOrder(Order.asc("name"))
.list();
并转换为cat集合,例如使用lambda-j(OnToOne关系不是懒,所以加载了Cat)
final List<Cat> cats = extract(kittens, on(Kitten.class).getMother());
<强> 子查询 强>
正如您所指出的那样,使用子查询是没有用的,因为Kitten属性的排序是不可能的
final DetachedCriteria q = DetachedCriteria.forClass(Kitten.class)
.createAlias("mother", "c")
.add(Restrictions.like("name", "name_of_a_kitten"))
.setProjection(Projections.property("c.id"));
final List<Cat> cats = session.createCriteria(Cat.class)
.add(Property.forName("id").in(q)).list(); //not possible order by Kitten attributes