Hibernate Criteria导致笛卡尔积与HSQL不一样:Spring Template问题?

时间:2011-03-18 18:22:58

标签: hibernate spring orm

我有两个实体CustomerAddress

假设约翰(Customer)有五个地址,那么以下两种方法会返回不同的结果

import org.springframework.orm.hibernate3.HibernateTemplate;

    @SuppressWarnings("unchecked")
    public List<Customer> getByNameCriteria(String firstName)
    {
        DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
        criteria.add(Restrictions.eq("firstName", firstName));
        return (List<ReposTable>)hibernateTemplate.findByCriteria(criteria);
    }

    @SuppressWarnings("unchecked")
    public List<Customer> getByNameHSQL(String firstName)
    {
        return (List<Customer>) hibernateTemplate.findByNamedParam("from Customer t where t.firstName=:firstName","firstName",firstName);

    }

客户端代码段

 List<Customer> allCustomers1 = rtRep.getByNameCriteria("John"); 

- &GT;返回5行:每行包含一个地址列表

 List<Customer> allCustomers2 = rtRep.getByNameHSQL("John"); 

- &GT;返回1行:带有地址列表

客户到地址是一对多的协会如下

@OneToMany(targetEntity=Address.class, fetch =  FetchType.EAGER, mappedBy="customer" )
@Cascade (value={CascadeType.SAVE_UPDATE })
private Set<Address> addresses = new HashSet<Address>();  

问题

  • 为什么标准行为有误,它发出了一个笛卡尔积查询,其中HSQL发出两个单独的查询,一个用于Customer,另一个用于Address并显示预期结果。

  • 这是否与以下内容有关:setResultTransformer,不同的根实体问题,请澄清。

由于

1 个答案:

答案 0 :(得分:4)

这是一个众所周知的行为(虽然我找不到任何明确定义为有效的来源)。

您需要应用结果转换器

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

或配置Hibernate以获取与SELECT

的关系
@OneToMany(targetEntity=Address.class, fetch =  FetchType.EAGER, mappedBy="customer" )    
@Cascade (value={CascadeType.SAVE_UPDATE })
@Fetch(FetchMode.SELECT)
private Set<Address> addresses = new HashSet<Address>();   

请注意,在某些情况下(特别是如果您希望查询返回多个Customers,并且每个Customer都有Address个es)查询JOIN可以出于性能原因首选。