简体   繁体   中英

Hibernate (JPA) inheritance mapping of abstract super classes

My data model represents legal entities, such as a Business or a Person. Both are tax-paying entities, and both have a TaxID, a collection of phone numbers, and a collection of mailing addresses.

I have a Java model with two concrete classes that extend an abstract class. The abstract class has properties and collections that are common to both concrete classes.

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

I'm using Hibernate JPA Annotations on a MySQL database, with classes like this:

@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;
}

The problem is that Phone and Address objects need to refer to their owner, which is an AbstractLegalEntity . Hibernate complains:

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

It seems like this would be a fairly common Java inheritance scenario, so I hope that Hibernate would support it. I've tried changing the mapping for AbstractLegalEntity based on a Hibernate forum question , no longer using @MappedSuperclass :

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

However, now I get the following error. When reading up on this inheritance mapping type, it looks like I have to use SEQUENCE not IDENTITY, and MySQL doesn't support SEQUENCE.

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

I'm making more progress toward getting things working when I use the following mapping.

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

I'm thinking I should continue down this path. My concern is that I'm mapping it as an @Entity when I really don't ever want an instance of AbstractLegalEntity to ever exist. I'd like to know if this is the right approach. What is the correct approach I should be taking for this situation?

Use:

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

In the database you will have one table for AbstractLegalEntity , and tables for classes, which extend AbstractLegalEntity class. You won't have instances of AbstractLegalEntity if it's abstract. Polymorphism can be used here.

When you use:

    @MappedSuperclass
    AbstractLegalEntity
    
    @Entity
    ConcretePersonEntity extends AbstractLegalEntity

This will create only one table in your database called ConcretePersonEntity , containing columns from both classes.

Add @Entity annotation to AbstractLegalEntity . Instance of AbstractLegalEntity will never exist - hibernate will load appropriate extending instances - ConcreteBusinessEntity or ConcretePersonEntity according to Id field.

You have to declare AbstracLegalEntity as an @Entity . Even with the @Entity annotation, your class remains abstract. consequently, you will only have instance of concrete subclasses.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM