I'm trying to set up polymorphic behaviour using Hibernate with JPA annotations.
It seems sensible (maybe even necessary) to create an (abstract) class encapsulating the state and behaviours required for the inheritance hierarchy to participate in persistence; for example
- I need to annotate an Id property, which I cannot do in an interface without making the field public, in order to avoid a 'No identifier specified on Entity' exception on the superclass
- I need subclasses to provide a DiscriminatorValue if I use the table-per-class-hierarchy approach
Is inheriting from an abstract class coupled to persistence in this way a good or bad practise? What are the pros/cons? Are there best practises around handling inheritance in JPA?
I'm not sure there is an absolute answer to your questions, it really depends on your particular situation and what you want to represent from a OO point of view. Providing some example would probably help.
But I suspect that you might want to read about the Mapped Superclasses. Here is a little extract from the JPA specification:
An entity may inherit from a
superclass that provides persistent
entity state and mapping information,
but which is not itself an entity.
Typically, the purpose of such a
mapped superclass is to define state
and mapping information that is common
to multiple entity classes.
A mapped superclass, unlike an entity,
is not queryable and cannot be passed
as an argument to EntityManager
or
Query
operations. A mapped
superclass cannot be the target of a
persistent relationship.
Both abstract and concrete classes may
be specified as mapped superclasses.
The MappedSuperclass
annotation (or
mapped-superclass
XML descriptor
element) is used to designate a mapped
superclass.
A class designated as
MappedSuperclass
has no separate
table defined for it. Its mapping
information is applied to the entities
that inherit from it.
And I think that you should also read about the various inheritance strategies to represent inheritance at the database level (single table per class hierarchy, table per concrete class, joined subclass) supported by JPA as they don't provide the same level of support for polymorphic queries. The JPA specification covers this decently.
Below relevant references.
References
- JPA 1.0 specification
- 2.1.9 Inheritance
- 2.1.10 Inheritance Mapping Strategies
- Hibernate Annotations Reference Guide
- 2.2.4. Mapping inheritance
- 2.2.4.4. Inherit properties from superclasses