抽象超类的休眠 (JPA) 继承映射

2022-09-01 09:48:39

我的数据模型表示法人实体,例如企业或个人。两者都是纳税实体,并且都有一个TaxID,一个电话号码集合和一个邮寄地址集合。

我有一个Java模型,其中包含两个扩展抽象类的具体类。抽象类具有两个具体类共有的属性和集合。

AbstractLegalEntity        ConcreteBusinessEntity    ConcretePersonEntity
-------------------        ----------------------    --------------------
Set<Phone> phones          String name               String first
Set<Address> addresses     BusinessType type         String last
String taxId                                         String middle

Address                    Phone
-------                    -----
AbsractLegalEntity owner   AbstractLegalEntity owner
String street1             String number
String street2           
String city
String state
String zip

我在MySQL数据库上使用Hibernate JPA Annotations,其类如下所示:

@MappedSuperclass
public abstract class AbstractLegalEntity {
    private Long id;  // Getter annotated with @Id @Generated
    private Set<Phone> phones = new HashSet<Phone>();  // @OneToMany
    private Set<Address> address = new HashSet<Address>();  // @OneToMany
    private String taxId;
}

@Entity
public class ConcretePersonEntity extends AbstractLegalEntity {
    private String first;
    private String last;
    private String middle;
}

@Entity
public class Phone {
    private AbstractLegalEntity owner; // Getter annotated @ManyToOne @JoinColumn
    private Long id;
    private String number;
}

问题在于,对象需要引用其所有者,即 .休眠抱怨:PhoneAddressAbstractLegalEntity

@OneToOne or @ManyToOne on Phone references an unknown 
entity: AbstractLegalEntity

这似乎是一个相当常见的Java继承场景,所以我希望Hibernate会支持它。我尝试根据Hibernate论坛问题更改抽象法律实体的映射,不再使用:@MappedSuperclass

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

但是,现在我收到以下错误。在阅读此继承映射类型时,看起来我必须使用SEQUENAMENT而不是IDENTITY,并且MySQL不支持SEQUENCE。

Cannot use identity column key generation with <union-subclass> 
mapping for: ConcreteBusinessEntity

当我使用以下映射时,我在使事情正常工作方面取得了更大的进展。

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
        name="entitytype",
        discriminatorType=DiscriminatorType.STRING
)

我想我应该继续沿着这条路走下去。我担心的是,当我真的不希望抽象法律实体的实例存在时,我会将其映射为一个。我想知道这是否是正确的方法。对于这种情况,我应该采取什么正确的方法?@Entity


答案 1

用:

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    AbstractLegalEntity

在数据库中,您将有一个用于 的表和用于扩展类的类的表。你不会有如果它是抽象的实例。多态性可以在这里使用。AbstractLegalEntityAbstractLegalEntityAbstractLegalEntity

当您使用时:

    @MappedSuperclass
    AbstractLegalEntity
    
    @Entity
    ConcretePersonEntity extends AbstractLegalEntity

这将在数据库中只创建一个名为 的表,其中包含两个类中的列。ConcretePersonEntity


答案 2

向 添加注释。的实例将永远不会存在 - 休眠将加载适当的扩展实例 - 或根据Id字段。@EntityAbstractLegalEntityAbstractLegalEntityConcreteBusinessEntityConcretePersonEntity


推荐