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.
精彩评论