开发者

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;
    pri开发者_JS百科vate 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜