我有Employee
(父母)和Emp_Contacts
(孩子)。只有Employee
类具有单向映射。
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
@Table(name="EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Size(min=3, max=50)
@Column(name = "NAME", nullable = false)
private String name;
...
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "emp_id")
private Set<Emp_Contacts> contacts;
...getters and setters...
我的Emp_Contacts
如下:
@Entity
@Table(name = "Emp_Contacts")
public class Emp_Contacts implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int emp_contact_id;
@NotNull
@Column(name = "emp_id")
private long emp_id;
....
数据库表对emp_contacts
上的emp_id
表没有空FK约束。
persist(employee)
将保留员工和相应的emp_contacts。使用FK约束我得到以下错误:
MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
我在互联网上搜索并找到了此链接https://forum.hibernate.org/viewtopic.php?f=1&t=995514
但是,如果我在Employee
中加入可空:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "emp_id", nullable = false)
private Set<Emp_Contacts> contacts
我的服务器甚至没有启动,我得到以下错误:
Repeated column in mapping for entity: com.cynosure.model.Emp_Contacts
column: emp_id (should be mapped with insert="false" update="false")
我做错了什么?
答案 0 :(得分:6)
Employee
是拥有方的协会(因为它是唯一的一方)。这样,外键总是与插入关联的Emp_Contacts
实例分开更新,因此它必须是可空的。
建议的解决方案是使关联成为双向关联,并使多方成为关联的所有者:
public class Employee {
@OneToMany(mappedBy = "employee")
private Set<Emp_Contacts> contacts;
}
public class Emp_Contacts {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "emp_id", nullable = false)
private Employee employee;
}
这样,外键可以不为空,并且您可以避免额外语句更新外键的成本,因为插入Emp_Contacts
时设置了外键值。
此外,您将始终在Emp_Contacts
实例中拥有关联的员工ID(似乎是您的意图)。您不必从数据库加载员工以访问其ID,因为可以将关联声明为惰性(如上例所示),Hibernate将生成仅包含id的代理。有关详细信息,请参阅this answer。
另一个好处是,您可以在需要时从双方导航关联(在HQL / JPQL查询中也很有用)。
如果您仍然想使用原始解决方案(单方面只与多方的普通外键值关联),那么使连接列可以为空并生成emp_id
属性insertable = false, updatable = false
,因为Hibernate在Employee
端保持关联时将自动更新映射的外键列:
@Column(name = "emp_id, insertable = false, updatable = false")
private long emp_id;
答案 1 :(得分:0)
我不确定这里,但您可以尝试删除
@NotNull
@Column(name = "emp_id")
private long emp_id;
来自班级Emp_Contacts
的。对我而言,看起来Hibernate抱怨emp_id
的重复映射,并且您已经在Employee
中映射了该列。
答案 2 :(得分:0)