gpt4 book ai didi

java - 一对多单向关系的外键约束问题

转载 作者:可可西里 更新时间:2023-11-01 06:37:07 25 4
gpt4 key购买 nike

我有 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_id 上的 emp_contacts 表,DB 表没有空 FK 约束。

  1. 如果我删除上述约束,则 persist(employee) 将保留员工和相应的 emp_contacts。
  2. 使用 FK 约束我得到以下错误:

    MySQLIntegrityConstraintViolationException:无法添加或更新子行:外键约束失败

我在互联网上搜索并找到了这个链接 https://forum.hibernate.org/viewtopic.php?f=1&t=995514

但是如果我在 Employee 中放入 nullable:

@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")

我做错了什么?

最佳答案

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,因为在Employee端维护关联时Hibernate会自动更新映射的外键列:

@Column(name = "emp_id, insertable = false, updatable = false")
private long emp_id;

关于java - 一对多单向关系的外键约束问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36315269/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com