2014-04-13 65 views
2

我有两个实体单向@OneToMany映射不是父者的名单:Hibernate的标准 - 得到相关实体,

@Entity 
@Table(name = "table1") 
public class A { 
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
    Integer pk; 

    String name; 

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @JoinColumn(name = "a_pk", nullable = false) 
    @Where(clause = "is_deleted = 0") 
    List<B> children; 
} 

@Entity 
@Table(name = "table2") 
public class B { 
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) 
    Integer pk; 

    String content; 

    @Column(name = "is_deleted",nullable=false) 
    @NotNull 
    boolean deleted = false; 
} 

我想获得所有的B实体,这是孩子们的名单属于匹配限制的实体

Criteria c = session.createCriteria(A.class) 
    .add(Restriction.like("name", "Test%")) 
    .createAlias("children","b"); 
??? 

而这正是我坚持:c.list()将返回我这样的对象的列表。我不关心A,我想B,我怎么用Hibernate标准/预测来做到这一点?如果有问题,我使用休眠4.2.12

在这个简化的情况下,只需要热切地取出是有意义的;在实际情况中,有四个OneToMany单向关联链,并且我想知道所有根(或更好,还有一些)孩子知道根id,但我不想加载所有中间的东西(这不是必需的,即使连接提取四个表格也是可行的)。另外,简单地获取root并追踪懒惰关联就是升级N + 1问题的一个明显例子。

作为一个侧面的问题,Hibernate标准是否满足entity/property @Where限制?

+2

我相信你可以做到这一点与投影的方式。但更简单的方法是根据其父项的属性从“B”中选择。 –

+0

从hibernate文档中我可以理解,我可以通过使用HQL作为'session.createQuery(“从A中选择b作为join a.children作为b,其中a.name类似于'Test%'')”来实现我所需要的。名单()'。我会稍后再尝试,如果我成功,我会更新。 – enlait

+0

或者,正如我所说的,“从B这里b.a.name像'Test%''。更简单否? –

回答

0

所以,是的,我最终使用HQL去了。没什么特别的。

List<B> bList = session.createQuery(
     "select b from A as a join a.children as b where a.name like 'Test%'" 
     ).list(); 
2

您可以使用投影来获取“b”列表。就像这样:

Criteria c = session.createCriteria(A.class) 
    .add(Restriction.like("name", "Test%")) 
    .createAlias("children","b").setProjection(Projections.property("b")); 
在此之后

当您尝试使用c.list()它将返回b的列表才能得到结果。 我希望这可以帮助!

+0

投影不能是一个对象。它会导致'org.hibernate.QueryException:无法解析属性:b'。您必须指定儿童的财产才能做到这一点 –