I am using Play Framework 1.2.4 with PostgreSQL
and JPA
. I would like to have a Model hierarchy and see that there are some alternatives to doing this.
I have a base class (which is abstract) and two concrete classes extending this base class. I don't want to persist this base class while I want to have concrete classes. In the base class, I have another Model classes as properties, in other words, I have @ManyToOne
relationships in my base class.
My question is what is the best way of implementing this? Using @MappedSuperclass
or @Inheritance
with TABLE_PER_CLASS
strategy? I am a bit confused as they seem virtually equivalent.
I also have some concerns about querying and performance issues that I might face in future.
Single Table. The single table strategy maps all entities of the inheritance structure to the same database table. This approach makes polymorphic queries very efficient and provides the best performance.
Inheritance is the core concept of object oriented language, therefore we can use inheritance relationships or strategies between entities. JPA support three types of inheritance strategies such as SINGLE_TABLE, JOINED_TABLE, and TABLE_PER_CONCRETE_CLASS.
The annotation @Inheritance is used on the root entity class with strategy = InheritanceType. SINGLE_TABLE . @DiscriminatorColumn is used on the root entity class to specify the discriminator column attributes. Discriminator is a way to differentiate rows belonging to different classes in the hierarchy.
A “join” strategy, whereby fields or properties that are specific to a subclass are mapped to a different table than the fields or properties that are common to the parent class.
MappedSuperClass must be used to inherit properties, associations, and methods.
Entity inheritance must be used when you have an entity, and several sub-entities.
You can tell if you need one or the other by answering this questions: is there some other entity in the model which could have an association with the base class?
If yes, then the base class is in fact an entity, and you should use entity inheritance. If no, then the base class is in fact a class that contains attributes and methods that are common to several unrelated entities, and you should use a mapped superclass.
For example:
@MappedSupperclass
is different than the @Inheritance
annotation.
@MappedSuperclass
tells the JPA provider to include the base class persistent properties as if they were declared by the child class extending the superclass annotated with @MappedSuperclass
.
However, the inheritance is only visible in the OOP world, since, from a database perspective, there's no indication of the base class. Only the child class entity will have an associated mapped table.
The @Inheritance
annotation is meant to materialize the OOP inheritance model in the database table structure. More, you can query a base class annotated with @Inheritance
but you can't do that for a base class annotated with @MappedSuperclass
.
Now, the reason why you'd want to use the @Inheritance
JPA annotation is to implement behavior-driven patterns like the Strategy Pattern.
On the other hand, @MappedSuperclass
is just a way to reuse both basic properties, associations, and even the entity @Id
using a common base class. Nevertheless, you can achieve almost the same goal using an @Embeddable
type. The only major difference is that you can't reuse an @Id
definition with @Embeddable
, but you can do it with @MappedSuperclass
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With