使用hibernate条件查询来加入非直接引用的实体

时间:2014-10-29 13:45:57

标签: java hibernate criteria hibernate-criteria

我想使用与另一个实体的连接在实体上运行条件查询。但是从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。

1 个答案:

答案 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