我有两个实体Customer
和Address
。
假设约翰(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");
客户到地址是一对多的协会如下
@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,不同的根实体问题,请澄清。
由于
答案 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
可以出于性能原因首选。