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. Advanced validation | 19. Refining the standard behavior | 20. Behavior & business logic | 21. References & collections | A. Architecture & philosophy | B. Java Persistence API | C. Annotations | D. Automated testing

Table of contents

Lesson 6: Mapped superclass inheritance
Mapped superclass
Simplify your entities
Summary
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
 
}

Simplify your entities

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.

Any problem with this lesson? Ask in the forum Everything fine? Go to Lesson 7