JPA - 映射多个OneToOne实体选项

时间:2015-11-30 13:20:27

标签: hibernate oop jpa

我们有一个名为Enterprise的实体和一些引用和定义Enterprise对象类型的实体,例如SubsidiaryCarrierAgentSupplierClient。每个Enterprise对象可以是一种或多种类型。

今天我们有基于连接列的映射,这些映射由每个类型实体映射,例如在我们拥有的Supplier上:

 @Entity
 public class Enterprise {
      @Id
      private Integer id;
      ...
      @Column
      private Boolean isSupplier; 
      ...
 }

 @Entity
 public class Supplier {
      @Id
      private Integer id;

      @OneToOne(fetch=FetchType.LAZY)
      @JoinColumn(name="IDENTERPRISE")
      private Enterprise enterprise;

      // Some other fields specific to suppliers here
      ...
 }

其他实体遵循这种映射模型,但是由于延迟加载和其他问题而导致模型和关系持续存在问题,它变得难以维护并且导致混淆和更多映射问题,例如,假设我们有另一个名为Invoice的实体,我们需要指定ClientCarrier,这里的一些程序员更喜欢与Enterprise建立关系,然后使用字段值用于在服务类上找到正确的对象,其他程序员更喜欢直接与ClientCarrier建立关系,系统正在变成水果沙拉。

我知道@Embeddable个实体,我知道这可能是最好的解决方案,但我们的数据库专家说要避免信息太多,字段太多的表格,这就是@Embeddable原因。

也许继承是一个很好的解决方案,但我们不知道如何使用给定的方案来实现这一点,我们有Enterprise可以是ClientSupplier但JPA需要一个识别对象类型的鉴别器列。

我们决定更改这些实体,并尽可能使用最佳映射策略。

我们在Jean Merelis的评论中找到了here¹,这是一个如何做@OneToOne懒惰关系的例子,请参阅下面的英文来源:

 public class Person {
      @Id
      private Long id;

      @OneToOne(fetch=FetchType.LAZY, mappedBy="person")
      @PrimaryKeyJoinColumn
      private Address address;
 }

 public class Address {
      @Id
      private Long id;

      @OneToOne(optional=false)
      @MapsId
      @JoinColumn(name="person_id", referencedColumnName="id")
      private Person person;
}

通过这种方式,我们可以级联持久化操作并始终引用Enterprise实体,提供如下字段:

 @Entity
 public class Enterprise {
      @Id
      private Integer id;

      @OneToOne(mappedBy="enterprise", fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
      @PrimaryKeyJoinColumn
      private Supplier asSupplier;
      ...
 }

 @Entity
 public class Supplier {
      @Id
      @Column(name="IDSUPPLIER")
      private Integer id;

      @OneToOne(optional=false)
      @MapsId
      @JoinColumn(name="IDENTERPRISE")
      private Enterprise enterprise;

      // Some other fields specific to suppliers here
      ...
 }

所以,最后,我的问题,这是一个不错的选择吗?如果没有,你能提供一个如何做得更好的好例子吗?

¹:对不起葡萄牙语网站,但我没有找到这个例子的英文版。

0 个答案:

没有答案