【发布时间】:2019-05-17 19:29:27
【问题描述】:
我的 Spring Web 应用程序允许用户更新“员工”记录以更改字段或添加与此“员工”记录相关的新“电话”记录。但是,在添加新的“电话”记录后提交“员工”记录进行更新时,会抛出 SQL 错误异常。
问题在于“Phone”表上的“Employee”表的“employee_id”外键未在最终提交给数据库的 SQL 插入语句中设置。但是,在更新/合并的“EmployeeEntity”对象引用的“PhoneEntity”JPA 实体对象中,与employee_id 数据库字段关联的属性不为空,它设置为正在更新/合并的“EmployeeEnity”对象.
根据我对 JPA 的理解,当实体记录的插入语句提交到数据库时,应该设置与数据库字段关联的实体属性,但在这种情况下,它不是导致此错误的原因。
我已经尝试使用调试器单步执行,并且我已经验证创建的 PhoneEntity 对象是 EmployeeEntity 的 phones 属性的成员,并且相同的 PhoneEntity 的 employee属性设置为双向关系中的同一 EmployeeEntity 对象(具有相同的对象 ID)。
我还设置了hibernate.show_sql=true 以查看正在提交到数据库的 SQL 语句,它包含该语句(省略号是更多字段):
Hibernate:
insert
into
phone
(id, employee_id, ...)
values
(?, ?, ...)
这意味着它正在为新的PhoneEntity 对象插入一个新的phone。
在尝试运行此插入语句后,它会给出 SQL 错误“列 'employee_id' 不能为空”。不过就像我之前说的,我已经检查了调试器,employee 属性确实设置为EmployeeEntity 对象。
这是我的代码的简化示例:
@Entity
@Table(name = "employee")
public class EmployeeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@OneToMany(mappedBy="employee", cascade = {CascadeType.PERSIST})
private Set<PhoneEntity> phones = new HashSet<>();
...
}
@Entity
@Table(name = "phone")
public class PhoneEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;
@ManyToOne
@JoinColumn(name = "employee_id", nullable = false)
private EmployeeEntity employee;
...
}
具有由以下 SQL 语句创建的结构的表。
CREATE TABLE employee (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
...
);
CREATE TABLE phone (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
employee_id INT NOT NULL,
...
FOREIGN KEY(employee_id) REFERENCES employee(id)
);
以下是它实际将更新提交给实体管理器以对数据库进行更新的地方。
public void update(EmployeeDomain employee) {
EmployeeEntity entity = employeeDomainToEntity.transform(employee)
getEntityManager().merge(entity);
}
EmployeeEntity 和 PhoneEntity 对象是通过转换从 http 请求反序列化的类似域对象创建的。我将包含更多这部分代码,但正如我所提到的,我已经用我的调试器确认提交给合并的实际实体对象已经是我们期望的phones 的形式字段和employee 字段设置正确,因此最终实体应该是正确的。
【问题讨论】:
标签: java hibernate jpa jpa-2.0 jpa-2.1