openxava / documentation / Lesson 6: Mapped superclass inheritance
Course:
1. Getting started |
2. Basic domain model (1) |
3. Basic domain model (2) |
4. Refining the user interface |
5. Agile development |
6. Mapped superclass inheritance |
7. Entity inheritance |
8. View inheritance |
9. Java properties |
10. Calculated properties |
11. @DefaultValueCalculator in collections |
12. @Calculation and colections totals |
13. @DefaultValueCalculator from file |
14. Manual schema evolution |
15. Multi user default value calculation |
16. Synchronize persistent and computed propierties |
17. Logic from database |
18. Validating with @EntityValidator |
19. Validation alternatives |
20. Validation on remove |
21. Custom Bean Validation annotation |
22. REST service call from validation |
23. Attributes in annotations |
24. Refining the standard behavior |
25. Behavior & business logic |
26. References & collections |
A. Architecture & philosophy |
B. Java Persistence API |
C. Annotations |
D. Automated testing
Inheritance is a practical way to reuse code in the object oriented world. Using inheritance with JPA and OpenXava is as easy as using it in plain Java. We are going to use inheritance to remove repeated and boring code, like the UUID definition, we'll do it using JPA mapped superclasses.
If you don't like videos follow the instructions below.
Mapped superclass
The
Author,
Category and
Invoice classes have some common code, the
oid field definition:
@Id @GeneratedValue(generator="system-uuid") @Hidden
@GenericGenerator(name="system-uuid", strategy = "uuid")
@Column(length=32)
String oid;
This code is just the same for all those classes. You know that copy and paste is a mortal sin, so we have to look for a solution to remove the code repetition, to avoid our way to hell.
An elegant solution for this situation is inheritance. JPA allows you to exploit the concept of inheritance. One of them is to inherit from a mapped superclass. A mapped superclass is a Java class with JPA mapping annotations, but it is not an entity itself. Its only goal is to be used as superclass for an entity. Let's use it, and you'll see its utility quickly.
First, we move this common piece of code to a class marked as
@MappedSuperclass. We name it
Identifiable:
package com.yourcompany.invoicing.model;
import javax.persistence.*;
import org.hibernate.annotations.GenericGenerator;
import org.openxava.annotations.*;
import lombok.*;
@MappedSuperclass // Marked as mapped superclass instead of entity
@Getter @Setter
public class Identifiable {
@Id @GeneratedValue(generator="system-uuid") @Hidden
@GenericGenerator(name="system-uuid", strategy = "uuid")
@Column(length=32)
String oid; // Property definition includes OpenXava and JPA annotations
}
Now you can define
Author,
Category and
Invoice entities in a more succinct way. To see an example you have the new code for
Category here:
package com.yourcompany.invoicing.model;
import javax.persistence.*;
import lombok.*;
@Entity @Getter @Setter
public class Category extends Identifiable {
@Column(length=50)
String description;
}
The refactoring is plain vanilla.
Category now extends from
Identifiable and we have removed the
oid property. This way, not only is your code shorter, but it's more elegant, because you declare that your class is identifiable (the what, not the how), and you removed from your business logic class code that is somewhat technical.
Apply this same refactoring to the
Author and
Invoice entities. Moreover, from now on you'll extend most of your entities from the
Identifiable mapped superclass.
We have created our own
Identifiable class to see the advantage of using mapped superclasses, however OpenXava provides for you a ready to use
Identifiable class that you can find in the
org.openxava.model package. So in your next project you don't need to write the
Identifiable class again, just use the one included in OpenXava.
Summary
You have learned that a mapped superclass is a regular class with JPA mapping annotations that you can use as a base class for your entities. Moreover, you have learned how to use mapped superclasses to simplify your code.