java - 使用复合键在相关实体之间插入数据时出现休眠错误
问题描述
我正在尝试将数据插入到 @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。
解决方案
推荐阅读
- mongodb - Mongo 文本搜索多个短语 - AND、OR
- firebase-dynamic-links - 使用动态链接 API 获取原始链接
- javascript - 如何将 Google Recaptcha v2 实施到限制访问 Google Recaptcha 的 Web 应用程序
- python-3.x - python如何将id分配给字符串?
- bash - 使用 if else bash 脚本检查变量是否存在
- flutter - 如何动态本地化文本字段文本方向取决于用户输入到 rtl 或 ltr 方向
- javascript - Javascript中返回值的类型转换
- javascript - 更改主要内容而不更改整页
- python - PySNMP:如何在同一个代理中实现 CommandResponder 和 NotificationOriginator?
- reactjs - 没有根据反应中的状态变化触发 UseEffect