首页 > 解决方案 > 使用复合键在相关实体之间插入数据时出现休眠错误

问题描述

我正在尝试将数据插入到 @ManyToOne 关系端的实体中。两个表共享一个复合主键(尽管数据库根本没有任何约束)。我已将我的相关实体建模如下:

实体一:

@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "EMP_GOALS_PHASES")
public class EmployeeGoalsAssessmentPhasesJPA implements Serializable {

    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "APP_ID", referencedColumnName = "APP_ID"),
            @JoinColumn(name = "EMP_ID", referencedColumnName = "EMP_ID"),
            @JoinColumn(name = "CYCLE_ID", referencedColumnName = "CYCLE_ID"),
            @JoinColumn(name = "GOAL_ID", referencedColumnName = "GOAL_ID")
    })
    private EmployeeGoalsAssessmentJPA goalId;

    @Id
    @Column(name = "PHASE_ID")
    private Long phaseId;

    @Id
    @Column(name = "APP_ID")
    private Long appId;

    @Id
    @Column(name = "EMP_ID")
    private Long empId;

    @Id
    @Column(name = "CYCLE_ID")
    private Long cycleId;

    @Id
    @Column(name = "GOAL_ID")
    private Long goalIdentifier;

    @Column(name = "GOAL_RATE")
    private Double goalRate;

    @Column(name = "GOAL_WEIGHTED")
    private Double goalWeightedRate;

    @Column(name = "GOAL_COMMENT")
    private String goalComment;

    @Embedded()
    @AttributeOverrides({
            @AttributeOverride(name = "empId", column = @Column(name = "CREATED_BY")),
            @AttributeOverride(name = "creationDate", column = @Column(name = "CREATION_DATE")),
            @AttributeOverride(name = "updatedByEmpId", column = @Column(name = "LAST_UPDATED_BY")),
            @AttributeOverride(name = "lastUpdatedOn", column = @Column(name = "LAST_UPDATED_DATE")),
    })
    private ChangeHistory historyOfChanges;

第二实体:

@Builder
@AllArgsConstructor
@Entity
@Table(name="EMP_GOALS")
public class EmployeeGoalsAssessmentJPA implements Serializable{


    @Id
    @Column(name="APP_ID")
    private Long appId;

    @Id
    @Column(name="EMP_ID")
    private Long empId;

    @Id
    @Column(name="CYCLE_ID")
    private Long periodId;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "goals2019_generator")
    @SequenceGenerator(name="goals2019_generator", sequenceName = "GOALS2019_SEQ", allocationSize=25)
    @Column(name="GOAL_ID", nullable = false)
    private Long goalId;

    @Column(name = "GOAL_NAME")
    private String goalName;

    @Column(name="GOAL_DESC")
    private String description;

    @Column(name="GOAL_POSITION")
    private Long goalPosition;

    @Column(name="GOAL_MEASURE")
    private String goalMeasure;

    @Column(name="GOAL_WEIGHT")
    private Double goalWeight;

    @ManyToOne
    @JoinColumn(name = "MID_REV_STATUS_ID")
    private MidReviewStatusJPA midReviewStatus;

    @Column(name="MID_REV_COMMENT")
    private String midReviewComment;

    @OneToMany( mappedBy = "goalId", fetch = FetchType.EAGER)
    private Set<EmployeeGoalsAssessmentPhasesJPA> goalsAssessmentPhases = new HashSet<>();

    @Embedded
    @AttributeOverrides({
            @AttributeOverride(name = "empId", column = @Column(name = "CREATED_BY")),
            @AttributeOverride(name = "creationDate", column = @Column(name = "CREATION_DATE")),
            @AttributeOverride(name = "updatedByEmpId", column = @Column(name = "LAST_UPDATED_BY")),
            @AttributeOverride(name = "lastUpdatedOn", column = @Column(name = "LAST_UPDATED_DATE")),
    })
    private ChangeHistory historyOfChanges;

现在我想在 EmployeeGoalsAssessmentPhasesJPA 中保存或更新数据,这显然与 EmployeeGoalsAssessmentJPA 相关。问题是,每当我尝试这样做时,我都会在保存过程中收到错误消息,说 SqlExceptionHelper:142 - 索引 13 超出范围。我已经切换到休眠的调试模式,并设法弄清楚这是怎么回事:

select
        employeego_.PHASE_ID,
        employeego_.GOAL_ID,
        employeego_.EMP_ID,
        employeego_.CYCLE_ID,
        employeego_.APP_ID,
        employeego_.GOAL_COMMENT as GOAL_COM6_11_,
        employeego_.CYCLE_ID as CYCLE_ID4_11_,
        employeego_.GOAL_ID as GOAL_ID2_11_,
        employeego_.EMP_ID as EMP_ID3_11_,
        employeego_.APP_ID as APP_ID5_11_,
        employeego_.GOAL_RATE as GOAL_RAT7_11_,
        employeego_.GOAL_WEIGHTED as GOAL_WEI8_11_,
        employeego_.CREATION_DATE as CREATION9_11_,
        employeego_.CREATED_BY as CREATED10_11_,
        employeego_.LAST_UPDATED_DATE as LAST_UP11_11_,
        employeego_.LAST_UPDATED_BY as LAST_UP12_11_ 
    from
        EMP_GOALS_PHASES employeego_ 
    where
        employeego_.PHASE_ID=? 
        and employeego_.GOAL_ID=? 
        and employeego_.EMP_ID=? 
        and employeego_.CYCLE_ID=? 
        and employeego_.APP_ID=?
Hibernate: 
    select
        employeego_.PHASE_ID,
        employeego_.GOAL_ID,
        employeego_.EMP_ID,
        employeego_.CYCLE_ID,
        employeego_.APP_ID,
        employeego_.GOAL_COMMENT as GOAL_COM6_11_,
        employeego_.CYCLE_ID as CYCLE_ID4_11_,
        employeego_.GOAL_ID as GOAL_ID2_11_,
        employeego_.EMP_ID as EMP_ID3_11_,
        employeego_.APP_ID as APP_ID5_11_,
        employeego_.GOAL_RATE as GOAL_RAT7_11_,
        employeego_.GOAL_WEIGHTED as GOAL_WEI8_11_,
        employeego_.CREATION_DATE as CREATION9_11_,
        employeego_.CREATED_BY as CREATED10_11_,
        employeego_.LAST_UPDATED_DATE as LAST_UP11_11_,
        employeego_.LAST_UPDATED_BY as LAST_UP12_11_ 
    from
        EMP_GOALS_PHASES employeego_ 
    where
        employeego_.PHASE_ID=? 
        and employeego_.GOAL_ID=? 
        and employeego_.EMP_ID=? 
        and employeego_.CYCLE_ID=? 
        and employeego_.APP_ID=?
2019-12-16 19:44:26,720 TRACE  BasicBinder:65 - binding parameter [1] as [BIGINT] - [30]
2019-12-16 19:44:26,720 TRACE  BasicBinder:65 - binding parameter [2] as [BIGINT] - [1900]
2019-12-16 19:44:26,720 TRACE BasicBinder:65 - binding parameter [3] as [BIGINT] - [57]
2019-12-16 19:44:26,720 TRACE BasicBinder:65 - binding parameter [4] as [BIGINT] - [201912]
2019-12-16 19:44:26,720 TRACE  BasicBinder:65 - binding parameter [5] as [BIGINT] - [1]

insert 
    into
        EMP_GOALS_PHASES
        (GOAL_COMMENT, CYCLE_ID, GOAL_ID, EMP_ID, APP_ID, GOAL_RATE, GOAL_WEIGHTED, CREATION_DATE, CREATED_BY, LAST_UPDATED_DATE, LAST_UPDATED_BY, PHASE_ID) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: 
    insert 
    into
        EMP_GOALS_PHASES
        (GOAL_COMMENT, CYCLE_ID, GOAL_ID, EMP_ID, APP_ID, GOAL_RATE, GOAL_WEIGHTED, CREATION_DATE, CREATED_BY, LAST_UPDATED_DATE, LAST_UPDATED_BY, PHASE_ID) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

binding parameter [1] as [VARCHAR] - [TEST IF CHILD ENTITY ONLY GETS UPDATED IF PARENT IS UPDATED]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [2] as [BIGINT] - [201912]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [3] as [BIGINT] - [3750]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [4] as [BIGINT] - [57]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [5] as [BIGINT] - [1]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [6] as [DOUBLE] - [8.0]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [7] as [DOUBLE] - [26.6]
2019-12-16 19:44:26,779 TRACE  BasicBinder:65 - binding parameter [8] as [DATE] - [2019-12-16]
2019-12-16 19:44:26,779 TRACE BasicBinder:65 - binding parameter [9] as [BIGINT] - [57]
2019-12-16 19:44:26,780 TRACE  BasicBinder:65 - binding parameter [10] as [DATE] - [2019-12-16]
2019-12-16 19:44:26,780 TRACE  BasicBinder:65 - binding parameter [11] as [BIGINT] - [57]
2019-12-16 19:44:26,780 TRACE  BasicBinder:65 - binding parameter [12] as [BIGINT] - [30]
2019-12-16 19:44:26,780 TRACE BasicBinder:65 - binding parameter [13] as [BIGINT] - [1900]
2019-12-16 19:44:26,781 INFO   AbstractBatchImpl:193 - HHH000010: On release of batch it still contained JDBC statements
2019-12-16 19:44:26,781 WARN   SqlExceptionHelper:137 - SQL Error: 0, SQLState: S1093
2019-12-16 19:44:26,781 ERROR  SqlExceptionHelper:142 - The index 13 is out of range.

现在,显然这个索引 13 不是我的表中的东西,那么为什么 Hibernate 会尝试使用它来插入数据呢?我对 Hibernate 的运作方式感到困惑。我认为由于对复合键的处理不当,我的模型也很混乱,但是我想了解那里发生了什么。

业务目标很简单:能够为一个目标保存多个阶段并在更新时对其进行更新。为简洁起见,我省略了 getter、setter 和 equals 以及 hashCode。我的数据库是 SQL Server。

标签: javasql-serverhibernate

解决方案


推荐阅读