不同类型的JPA映射FK
JPA mapping FK of different types
现在我使用 JPA 创建简单的一对多关系的方法是这样的:
实体 A Table
@Table(name = "EntityA", schema = "schema")
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@OneToMany(mappedBy = "EntityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<EntityB> entitiesB;
}
实体 B Table
@Table(name = "EntityB", schema = "schema")
public class EntityB {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@ManyToOne
@JoinColumn(name = "entityA_id")
private EntityA entityA;
}
现在另一个 table 开始发挥作用,EntityB 中的 ManyToOne
列可能是 EntityA 类型或 EntityC 类型,我的第一个猜测是使用泛型,但我无意中遇到了同样的问题post 我在遵循随附的文档时遇到了一些困难。
有没有更简单的方法来解决这个问题?
考虑到 EntityA 和 EntityC 都有一个唯一的自动生成的 Integer id,我正在考虑将 manyToOne
列声明为 Integer
,但我不知道这是否可行方法和某种程度上我想在我的所有应用程序中遵循一些一致性。
您可以通过两种方式解决此问题:
- 如果
EntityB
和 EntityC
彼此独立,则您将模型 2 分开 one-to-many associations。 (这是最常见的方法)
- 如果
EntityB
和 EntityC
共享一个超类,您可以建模和映射继承层次结构并使用多态关联映射。
选项 1:2 个单独的关联
这种方法是最常见的方法,因为它易于实施且非常灵活。如果 EntityB
和 EntityC
不属于同一继承层次,则应使用它。
@Entity
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(mappedBy = "entityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<EntityB> entitiesB;
@OneToMany(mappedBy = "entityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<EntityC> entitiesC;
// getter and setter methods ...
}
我保留了级联和orphanRemoval settings you used in your initial mapping. Please double-check them before you deploy this to production. Both should only be used for parent-child associations. Especially CascadeType.REMOVE
, which is included in CascadeType.ALL
, can have some negative side effects。
选项 2:1 多态关联
如果EntityB
和EntityC
属于同一个继承层次,而你使用JPA's inheritance mappingInheritanceType.JOINED
或InheritanceType.SINGLE_TABLE
,你可以使用多态关联映射.
(注意:InheritanceType.TABLE_PER_CLASS
也支持多态关联,但查询变得非常复杂,这通常会导致性能问题,应避免。)
在为继承层次建模后,您可以定义与共享超类的关联。该关联包括所有子类。当您从数据库中获取此关联时,您的持久性提供程序会为每条记录实例化正确的子类,并将其 returns 作为超类的集合。
@Entity
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(mappedBy = "entityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<SuperEntity> superEntities;
// getter and setter methods ...
}
现在我使用 JPA 创建简单的一对多关系的方法是这样的:
实体 A Table
@Table(name = "EntityA", schema = "schema")
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@OneToMany(mappedBy = "EntityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<EntityB> entitiesB;
}
实体 B Table
@Table(name = "EntityB", schema = "schema")
public class EntityB {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@ManyToOne
@JoinColumn(name = "entityA_id")
private EntityA entityA;
}
现在另一个 table 开始发挥作用,EntityB 中的 ManyToOne
列可能是 EntityA 类型或 EntityC 类型,我的第一个猜测是使用泛型,但我无意中遇到了同样的问题post 我在遵循随附的文档时遇到了一些困难。
有没有更简单的方法来解决这个问题?
考虑到 EntityA 和 EntityC 都有一个唯一的自动生成的 Integer id,我正在考虑将 manyToOne
列声明为 Integer
,但我不知道这是否可行方法和某种程度上我想在我的所有应用程序中遵循一些一致性。
您可以通过两种方式解决此问题:
- 如果
EntityB
和EntityC
彼此独立,则您将模型 2 分开 one-to-many associations。 (这是最常见的方法) - 如果
EntityB
和EntityC
共享一个超类,您可以建模和映射继承层次结构并使用多态关联映射。
选项 1:2 个单独的关联
这种方法是最常见的方法,因为它易于实施且非常灵活。如果 EntityB
和 EntityC
不属于同一继承层次,则应使用它。
@Entity
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(mappedBy = "entityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<EntityB> entitiesB;
@OneToMany(mappedBy = "entityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<EntityC> entitiesC;
// getter and setter methods ...
}
我保留了级联和orphanRemoval settings you used in your initial mapping. Please double-check them before you deploy this to production. Both should only be used for parent-child associations. Especially CascadeType.REMOVE
, which is included in CascadeType.ALL
, can have some negative side effects。
选项 2:1 多态关联
如果EntityB
和EntityC
属于同一个继承层次,而你使用JPA's inheritance mappingInheritanceType.JOINED
或InheritanceType.SINGLE_TABLE
,你可以使用多态关联映射.
(注意:InheritanceType.TABLE_PER_CLASS
也支持多态关联,但查询变得非常复杂,这通常会导致性能问题,应避免。)
在为继承层次建模后,您可以定义与共享超类的关联。该关联包括所有子类。当您从数据库中获取此关联时,您的持久性提供程序会为每条记录实例化正确的子类,并将其 returns 作为超类的集合。
@Entity
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(mappedBy = "entityA", cascade = {CascadeType.ALL}, orphanRemoval = true)
private List<SuperEntity> superEntities;
// getter and setter methods ...
}