【问题标题】:Why hibernate add to my query cross join at the end为什么休眠在最后添加到我的查询交叉连接
【发布时间】:2017-01-14 03:26:21
【问题描述】:

我正在通过这个基于 Hibernate 的代码构建和运行查询:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = cb.createTupleQuery();
Root<hisaVO> hisa = criteria.from(hisaVO.class);
Root<EstablecVO> establec = criteria.from(EstablecVO.class);
Root<DisaVO> disa = criteria.from(DisaVO.class);
Root<RedVO> red1 = criteria.from(RedVO.class);
Root<MicroredVO> microred = criteria.from(MicroredVO.class);
Root<Unidad_EjecutoraVO> ue1 = criteria.from(Unidad_EjecutoraVO.class);
Join<hisaVO,EstablecVO> j1 = hisa.join("estab");
Join<EstablecVO,DisaVO> j2 = j1.join("disa") ;
Join<EstablecVO,RedVO> j3 = j1.join("red") ;
Join<EstablecVO,MicroredVO> j4 = j1.join("microred") ;
Join<EstablecVO,Unidad_EjecutoraVO> j5 = j1.join("ue") ;

criteria.multiselect(j3.get("red_nombre"), cb.count(hisa))
  .groupBy(red1.get("red_nombre"));

return em.createQuery(criteria).getResultList();  

日志显示 Hibernate 正在通过相应的 SQL 实现它:

select
  redvo3_.red_nombre as col_0_0_,
  count(hisavo0_.id) as col_1_0_
from
  hisa hisavo0_
  inner join establec establecvo6_ 
    on hisavo0_.cod_estab=establecvo6_.COD_ESTAB
  inner join disa disavo7_
    on establecvo6_.cod_disa=disavo7_.id
  inner join red redvo8_
    on establecvo6_.cod_red=redvo8_.id
  inner join microred microredvo9_
    on establecvo6_.cod_mic=microredvo9_.id
  inner join unidad_ejecutora unidad_eje10_
    on establecvo6_.cod_ue=unidad_eje10_.id
  cross join establec establecvo1_
  cross join disa disavo2_
  cross join red redvo3_
  cross join microred microredvo4_
  cross join unidad_ejecutora unidad_eje5_
group by redvo3_.red_nombre

它似乎在查询末尾添加了额外的意外cross joins。为什么要这样做?

【问题讨论】:

  • 问题是因为它在末尾添加了交叉连接和我的查询性能延迟......我有 1000 万条数据:(
  • 您是在询问最后两个交叉连接——microredvo4_unidad_eje5_ 的交叉连接吗?
  • @JohnBollinger 我问的是因为如果它已经是内部连接,它会添加所有交叉连接......这种延迟导致查询

标签: java mysql sql-server hibernate join


【解决方案1】:

您通过多次调用CriteriaQuery.from() 为您的查询提供多个根。第一个之后的每个都通过cross join 反映在最终查询中。这就是作为查询根的含义

您不需要(也不应该)使用CriteriaQuery.from() 将实体添加到您打算通过对应于映射关系的内部联接关联的查询中——您通过用作@ 的Join 连接的实体987654325@ 运行查询时。

【讨论】:

  • “您不需要(也不应该)使用 CriteriaQuery.from() 将实体添加到您打算通过内部连接关联的查询中”您假设表将是加入主键。如果它们必须在任意键上连接,则别无选择,只能添加另一个表的根。很遗憾,criteria API 有这个限制。
  • 要点,@Amalgovinus。我已经改写为指定内部连接对应于映射关系,我认为这在逻辑上归结为。在实践中,这些确实是主键上的连接,但我认为即使主键上的连接也需要查询根 + 过滤条件,其中它们不对应于映射关系。
猜你喜欢
  • 2017-09-22
  • 2012-06-03
  • 2011-11-06
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 2015-04-17
相关资源
最近更新 更多