use*_*612 7 java mysql hibernate foreign-keys spring-mvc
我有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...
Run Code Online (Sandbox Code Playgroud)
我的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;
....
Run Code Online (Sandbox Code Playgroud)
对于emp_contacts表,DB表没有null FK约束emp_id.
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
Run Code Online (Sandbox Code Playgroud)
我的服务器甚至没有启动,我得到以下错误:
Repeated column in mapping for entity: com.cynosure.model.Emp_Contacts
column: emp_id (should be mapped with insert="false" update="false")
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么 ?
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;
}
Run Code Online (Sandbox Code Playgroud)
这样,外键可以不为空,并且您可以避免额外语句更新外键的成本,因为插入时设置了外键值Emp_Contacts.
此外,您将始终在Emp_Contacts实例中具有关联的员工ID (似乎是您的意图).您不必从数据库加载员工以访问其ID,因为可以将关联声明为惰性(如上例所示),Hibernate将生成仅包含id的代理.有关更多信息,请参阅此答案.
另一个好处是,您可以在需要时从双方导航关联(在HQL/JPQL查询中也很有用).
如果您仍然想使用原始解决方案(单方面只与普通外键值相关联),则使连接列可以为空并创建emp_id属性insertable = false, updatable = false,因为Hibernate将在维护关联时自动更新映射的外键列该Employee方:
@Column(name = "emp_id, insertable = false, updatable = false")
private long emp_id;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7328 次 |
| 最近记录: |