Hibernate对集合元素的限制与获取模式

时间:2015-05-12 15:26:58

标签: java mysql hibernate criteria

我正在使用Hibernate 4.3.8作为我们的MySql数据库的ORM工具。我有一个要映射的类,注释如下:

@Entity
@DynamicUpdate
@Table(name = "myclass")
public class MyClass {
    @Id
    @Column(name = "myClassId")
    private String id;

    @Column(name = "status")
    private String status;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "myclass_children", joinColumns = @JoinColumn(name = "myClassId"))
    @Column(name = "child")
    @Fetch(FetchMode.JOIN) 
    @BatchSize(size = 100) 
    @Cascade(value = CascadeType.ALL)
    private Set<String> children;
}

要通过Hibernate执行读取查询,我被要求使用Criteria API。我应该在开头提到使用HQL或SQL不是选项。

使用以下代码完全执行我想要执行的操作:执行第二个选择查询以检索集合元素并准确返回20个MyClass对象。

public List<MyClass> listEntities() {
    Session session = sessionFactory.openSession();
    try {
        Criteria criteria = session.createCriteria(MyClass.class);
        criteria.setFetchMode("children", FetchMode.SELECT);
        criteria.add(Restrictions.eq("status", "open"));
        criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        criteria.setMaxResults(20);  
    }
}

以下是生成的查询:

select 
    this.myClassId as myClassId_1_0_0,
    this.status as status_2_0_0
from 
    myclass this
where        
    status = ?
limit ?

select
    children0.myClassId as myClassId1_0_0,
    children0.child as child2_0_0
from
    myclass_children as children0_
where
    children0_.myClassId in (
        ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? 
    )

但是,当我尝试对集合元素施加限制时,hibernate会执行单个连接查询。当此单个查询的结果集中的行数(不是不同的根实体)达到限制时,Hibernate将返回现有的MyClass对象作为结果。如果每个MyClass对象为2个子对象,则返回10个MyClass对象。

public List<MyClass> listEntities() {
    Session session = sessionFactory.openSession();
    try {
        Criteria criteria = session.createCriteria(MyClass.class);
        criteria.setFetchMode("children", FetchMode.SELECT);
        criteria.createCriteria("children", "ch", JoinType.LEFT_OUTER_JOIN);
        criteria.add(Restrictions.eq("status", "open"));
        criteria.add(Restrictions.in("ch.elements", Arrays.asList("child1", "child2"));
        criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        criteria.setMaxResults(20);  
    }
}

以下是生成的查询:

select 
    this.id as id1_0_0,
    this.status as status2_0_0,
    ch.child as child1_0_2
from
    myclass this
left outer join
    myclass_children ch1_
        on this.myClassId = ch1_.myClassId
where
    this.status = ? limit ?

在添加对集合元素的限制时,如何获取20个MyClass对象?任何建议&amp;欢迎回答!

注意:@Fetch(FetchMode.JOIN)注释用于其他代码库(如通过id选择等)。它应该对我的问题没有任何影响,因为我分别为条件对象设置FetchMode.SELECT。

0 个答案:

没有答案