java - 为什么改变 joinColumn 的顺序,hibernate 返回正确或不正确的查询?

标签 java spring hibernate hibernate-annotations spring-annotations

问题:

为什么改变 joinColumn 的顺序,hibernate 返回正确或不正确的查询?

第一次加入:

@OneToOne
      @JoinTable(name="TTR_POA_UPA",
        joinColumns = {
          @JoinColumn(name="ANO", insertable=false, updatable=false),
          @JoinColumn(name="ID_ESCALA", insertable=false, updatable=false),
          @JoinColumn(name="MES", insertable=false, updatable=false)          
        },
        inverseJoinColumns = {
          @JoinColumn(name="ANO", insertable=false, updatable=false),
          @JoinColumn(name="ID_ESCALA", insertable=false, updatable=false),
          @JoinColumn(name="MES", insertable=false, updatable=false)
        }     
      )
private PoaUpa poaUpa;

返回:

Hibernate: select * from ( select autorizaci0_.ano as ano0_, autorizaci0_.ID_ESCALA as ID2_0_, autorizaci0_.mes as mes0_, autorizaci0_.AUTORIZACION_HORAS_DIA_FIJIS as AUTORIZA4_0_, autorizaci0_.AUTORIZACION_HORAS_EVENT as AUTORIZA5_0_, autorizaci0_.AUTORIZACION_HORAS_FACTP as AUTORIZA6_0_, autorizaci0_.AUTORIZACION_HORAS_FIJIS as AUTORIZA7_0_, autorizaci0_.AUTORIZACION_HORAS_FIJOS as AUTORIZA8_0_, autorizaci0_.AUTORIZACION_HORAS_SEM_FACTP as AUTORIZA9_0_, autorizaci0_.AUTORIZACION_NAP as AUTORIZ10_0_, autorizaci0_.AUTORIZACION_NUM_PERS_EVENT as AUTORIZ11_0_, autorizaci0_.AUTORIZACION_OBSERVACIONES as AUTORIZ12_0_, autorizaci0_.PETICION_HORAS_DIA_FIJIS as PETICION13_0_, autorizaci0_.PETICION_HORAS_EVENT as PETICION14_0_, autorizaci0_.PETICION_HORAS_FACTP as PETICION15_0_, autorizaci0_.PETICION_HORAS_FIJIS as PETICION16_0_, autorizaci0_.PETICION_HORAS_FIJOS as PETICION17_0_, autorizaci0_.PETICION_HORAS_SEM_FACTP as PETICION18_0_, autorizaci0_.PETICION_NAP as PETICION19_0_, autorizaci0_.PETICION_NUM_PERS_EVENT as PETICION20_0_, autorizaci0_.PETICION_OBSERVACIONES as PETICION21_0_, autorizaci0_.REALIZACION_HORAS_DIA_FIJIS as REALIZA22_0_, autorizaci0_.REALIZACION_HORAS_EVENT as REALIZA23_0_, autorizaci0_.REALIZACION_HORAS_FACTP as REALIZA24_0_, autorizaci0_.REALIZACION_HORAS_FIJIS as REALIZA25_0_, autorizaci0_.REALIZACION_HORAS_FIJOS as REALIZA26_0_, autorizaci0_.REALIZACION_HORAS_SEM_FACTP as REALIZA27_0_, autorizaci0_.REALIZACION_NAP as REALIZA28_0_, autorizaci0_.REALIZACION_NUM_PERS_EVENT as REALIZA29_0_, autorizaci0_.REALIZACION_OBSERVACIONES as REALIZA30_0_, autorizaci0_1_.ANO as ANO1_, autorizaci0_1_.ID_ESCALA as ID2_1_, autorizaci0_1_.MES as MES1_ from TTR_AUTORIZACION autorizaci0_ left outer join TTR_POA_UPA autorizaci0_1_ on autorizaci0_.ano=autorizaci0_1_.ANO and autorizaci0_.ID_ESCALA=autorizaci0_1_.ID_ESCALA and autorizaci0_.mes=autorizaci0_1_.MES where autorizaci0_.ano=? and autorizaci0_.mes=? and autorizaci0_.ID_ESCALA=? ) where rownum <= ?

通过此连接:

on autorizaci0_.ano=autorizaci0_1_.ANO and autorizaci0_.ID_ESCALA=autorizaci0_1_.ID_ESCALA

和第二次加入:

@OneToOne     
      @JoinTable(name="TTR_POA_UPA",
        joinColumns = {
          @JoinColumn(name="ID_ESCALA", insertable=false, updatable=false),
          @JoinColumn(name="ANO", insertable=false, updatable=false),
          @JoinColumn(name="MES", insertable=false, updatable=false)          
        },
        inverseJoinColumns = {
          @JoinColumn(name="ID_ESCALA", insertable=false, updatable=false),
          @JoinColumn(name="ANO", insertable=false, updatable=false),
          @JoinColumn(name="MES", insertable=false, updatable=false)
        }         )     
private PoaUpa poaUpa;

返回:

Hibernate: select * from ( select autorizaci0_.ano as ano0_, autorizaci0_.ID_ESCALA as ID2_0_, autorizaci0_.mes as mes0_, autorizaci0_.AUTORIZACION_HORAS_DIA_FIJIS as AUTORIZA4_0_, autorizaci0_.AUTORIZACION_HORAS_EVENT as AUTORIZA5_0_, autorizaci0_.AUTORIZACION_HORAS_FACTP as AUTORIZA6_0_, autorizaci0_.AUTORIZACION_HORAS_FIJIS as AUTORIZA7_0_, autorizaci0_.AUTORIZACION_HORAS_FIJOS as AUTORIZA8_0_, autorizaci0_.AUTORIZACION_HORAS_SEM_FACTP as AUTORIZA9_0_, autorizaci0_.AUTORIZACION_NAP as AUTORIZ10_0_, autorizaci0_.AUTORIZACION_NUM_PERS_EVENT as AUTORIZ11_0_, autorizaci0_.AUTORIZACION_OBSERVACIONES as AUTORIZ12_0_, autorizaci0_.PETICION_HORAS_DIA_FIJIS as PETICION13_0_, autorizaci0_.PETICION_HORAS_EVENT as PETICION14_0_, autorizaci0_.PETICION_HORAS_FACTP as PETICION15_0_, autorizaci0_.PETICION_HORAS_FIJIS as PETICION16_0_, autorizaci0_.PETICION_HORAS_FIJOS as PETICION17_0_, autorizaci0_.PETICION_HORAS_SEM_FACTP as PETICION18_0_, autorizaci0_.PETICION_NAP as PETICION19_0_, autorizaci0_.PETICION_NUM_PERS_EVENT as PETICION20_0_, autorizaci0_.PETICION_OBSERVACIONES as PETICION21_0_, autorizaci0_.REALIZACION_HORAS_DIA_FIJIS as REALIZA22_0_, autorizaci0_.REALIZACION_HORAS_EVENT as REALIZA23_0_, autorizaci0_.REALIZACION_HORAS_FACTP as REALIZA24_0_, autorizaci0_.REALIZACION_HORAS_FIJIS as REALIZA25_0_, autorizaci0_.REALIZACION_HORAS_FIJOS as REALIZA26_0_, autorizaci0_.REALIZACION_HORAS_SEM_FACTP as REALIZA27_0_, autorizaci0_.REALIZACION_NAP as REALIZA28_0_, autorizaci0_.REALIZACION_NUM_PERS_EVENT as REALIZA29_0_, autorizaci0_.REALIZACION_OBSERVACIONES as REALIZA30_0_, autorizaci0_1_.ID_ESCALA as ID2_1_, autorizaci0_1_.ANO as ANO1_, autorizaci0_1_.MES as MES1_ from TTR_AUTORIZACION autorizaci0_ left outer join TTR_POA_UPA autorizaci0_1_ on autorizaci0_.ano=autorizaci0_1_.ID_ESCALA and autorizaci0_.ID_ESCALA=autorizaci0_1_.ANO and autorizaci0_.mes=autorizaci0_1_.MES where autorizaci0_.ano=? and autorizaci0_.mes=? and autorizaci0_.ID_ESCALA=? ) where rownum <= ?

使用这个不正确的连接:

on autorizaci0_.ano=autorizaci0_1_.ID_ESCALA and autorizaci0_.ID_ESCALA=autorizaci0_1_.ANO

解决方案:

完美的解决方案是:(感谢@JB Nizet)

@OneToOne
  @JoinTable(name="TTR_POA_UPA",
    joinColumns = {
      @JoinColumn(name="ANO", insertable=false, updatable=false, referencedColumnName="ANO"),
      @JoinColumn(name="ID_ESCALA", insertable=false, updatable=false, referencedColumnName="ID_ESCALA"),
      @JoinColumn(name="MES", insertable=false, updatable=false, referencedColumnName="MES")          
    },
    inverseJoinColumns = {
      @JoinColumn(name="ANO", insertable=false, updatable=false, referencedColumnName="ANO"),
      @JoinColumn(name="ID_ESCALA", insertable=false, updatable=false, referencedColumnName="ID_ESCALA"),
      @JoinColumn(name="MES", insertable=false, updatable=false, referencedColumnName="MES")
    }     
  )
private PoaUpa poaUpa;

最佳答案

连接表的连接列引用连接表中的列。它在第一种情况下是偶然工作的,因为构成实体 ID 的列的顺序与连接列的顺序相同。您应该指定每个连接列的引用列名,以使事情更清晰和安全:

@JoinColumn(name="ID_ESCALA", insertable=false, updatable=false, referencedColumnName="ID_ASCALA"),
@JoinColumn(name="ANO", insertable=false, updatable=false, referencedColumnName="ANO"),
...

不过,带有连接表的 OneToOne 确实很奇怪。

关于java - 为什么改变 joinColumn 的顺序,hibernate 返回正确或不正确的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11342733/

相关文章:

java - xi :include does not exist because parser is looking from project root 的文件

java - 使一个 token 优先于另一个 token

java - 我已经将我的 Maven 依赖项的范围更改为提供

java - 将 ValidationMessages 捆绑与 Spring Webflow Validation 一起使用?

java - 异常: NumberFormatException: For input string in JSP list Page

spring - 使用来自不同数据库的 bean hibernate DuplicateMappingException

java - 如何更改两个位置之间的文本颜色?

java - 在 Java EE 应用程序中使用 servlet 中的 bean 类

java - 具有持久队列的服务器推送Java框架?

java - 通过注解对方法数组列表进行排序(Java 反射)