当前位置: 代码迷 >> java >> 具有接口和嵌入式的多对多
  详细解决方案

具有接口和嵌入式的多对多

热度:66   发布时间:2023-08-02 11:08:23.0

我想在Account实体和Pushable接口之间创建一个单向的@ManyToMany。 Pushable只是一个由两个类实现的标记接口:Package和Plan

包是一个简单的实体:

@Entity
public class Package extends BasicEntity{
}

但Plan是放置在Service实体中的嵌入对象:

@Entity
public class Service extends BasicEntity{

 @Embedded
 Plan plan;
}

BacicEntity为它的孩子提供了ID:

@MappedSuperclass
public abstract class BasicEntity{

  @Id
  @GeneratedValue(strategy = IDENTITY)
  @Column(name = "ID")
  protected Long id;
}

我的映射看起来像这样:

@Entity
public class Account extends Basicentity{

  @ManyToMany(cascade=CascadeType.ALL)
  @JoinTable(name="PUSHABLES_ACCOUNTS", joinColumns=@JoinColumn(name="ID"), 
  inverseJoinColumns=@JoinColumn(name="ID"))
  private List<Pushable>pushables = new ArrayList<Pushable>();
}

我主要担心的是:

  • 实体和接口之间的映射是否有效? (一般来说)
  • 在连接表中有两个ID列会有问题吗? 帐户和服务都从BasicEntity获得@Id

实体和接口之间的映射是否有效? (一般来说)

JPA规范定义了实体之间的关系。 JPA Spec 2.1声明接口必须“不被指定为实体”。 所以Pushable不能以任何便携方式成为关系的目标。 此外,您的Plan对象是一个嵌入式对象,它本身不是一个实体,也不能成为关系的目标。

在连接表中有两个ID列会有问题吗? 帐户和服务都从BasicEntity获得@Id

您设置的@JoinTable存在一个主要问题,无论接口是否为目标。

@ManyToMany(cascade=CascadeType.ALL)
  @JoinTable(name="PUSHABLES_ACCOUNTS", joinColumns=@JoinColumn(name="ID"), 
  inverseJoinColumns=@JoinColumn(name="ID"))

@JoinColumn(name="ID") ,'name'指的是链接表PUSHABLES_ACCOUNTS列的名称,对于inverseJoinColumns=@JoinColumn(name="ID"))也是如此inverseJoinColumns=@JoinColumn(name="ID"))所以,(并忽略了事实上,Pushables不是实体),您的joinColumns和inverseJoinColumns引用PUSHABLES_ACCOUNTS链接表中的相同列。 您需要将帐户的ID链接到Pushable的ID。 您可能希望连接表看起来如下所示:

       PUSHABLES_ACCOUNTS
**Account_ID**    **PUSHABLES_ID**
    005                 017
    ….                  ….

因此,您的连接表将是:

@ManyToMany(cascade=CascadeType.ALL)
  @JoinTable(name="PUSHABLES_ACCOUNTS", 
    joinColumns=@JoinColumn(name=" Account_ID ", referencedColumnName=”ID”), 
    inverseJoinColumns=@JoinColumn(name=" PUSHABLES_ID " , referencedColumnName=”ID”))

我在这里添加了referencedColumnName ,但默认情况下会使用这些值。 这些是源表(joinColumns)和目标表(inverseJoinColumns)的列。 此关系可能是自引用的,也可能是源表=目标表。


选项

因此,当前类图中来自Account的唯一可能关系目标是Package和Service。 因此,您可以从Account定义两个ManyToMany关系 - 一个到Package,一个到Service。 然后从每个服务实体中挖掘出嵌入式计划,并以这种方式构建Pushables列表。

根据您的业务需求,您可以获得相当多的灵活性,当接口,嵌入式,映射超类等非实体看起来需要成为关系的一部分时,考虑将这些实体推广或制作实体也可能有所帮助。

例如,将BasicEntity更改为MappedSuperclass的实体 - 您需要定义继承策略 - 然后您可以在Account和BasicEntity之间建立关系。

另一个选项 - 我还没有尝试过这个 - 是定义和抽象实体类,它扩展了BasicEntity并且是一个超级的包和服务。 然后,该类可以成为帐户中“多对多”的便捷目标,再次您需要考虑继承策略。

  相关解决方案