Freiheit Freiheit - 2 months ago 11
Java Question

Is it possible to build a JPA entity by extending a POJO?

Lets say I have the following POJO:

public class MyThing {
private int myNumber;
private String myData;
//assume getter/setter methods
}


Is it now possible to extend this POJO as a JPA entity?

@Entity
@Table(name = "my_thing")
public class MyThingEntity extends MyThing implements Serializable {
@Column(name = "my_number")
//?????????
@Column(name = "my_data")
//????????
}


I want to keep the POJO separate from the JPA entity. The POJO lives in a different project and is often used without a persistence layer, my project wants to persist it in a database and do so without the overhead of mapping from a POJO to an entity and back.

I understand that JPA entities are POJOs, but in order to use it I would have to include a library that implements javax.persistence and the other projects using the same base object have no use for a persistence layer.

Is this possible? Is this a good idea?

Answer

JPA specification states

Entities may extend non-entity classes as well as entity classes, and non-entity classes may extend entity classes.

@javax.persistence.MappedSuperclass annotation allows you to define this kind of mapping

@MappedSuperclass
public class MyThing implements Serializable {
    private int myNumber;
    private String myData;

    // getter's and setter's
}

And

@Entity
@Table(name="MY_THING")
public class MyThingEntity extends MyThing {


}

As said by JPA specification

The MappedSuperclass annotation designates a class whose mapping information is applied to the entities that inherit from it.

And

A class designated with the MappedSuperclass annotation can be mapped in the same way as an entity except that the mappings will apply only to its subclasses since no table exists for the mapped superclass itself.

If you need to override some property defined by MyThing, use @AttibuteOverride (when you want to override a single property) or @AttibuteOverrides (when you want to override more than one property)

@Entity
@Table(name="MY_THING")
@AttributeOverride(name="myData", column=@Column(name="MY_DATA"))
public class MyThingEntity extends MyThing {


}

If you do not want to change your base class, you can use xml to define it as a @MappedSuperClass

Be aware: by default, the persistence provider will look in the META-INF directory for a file named orm.xml

<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
    <mapped-superclass class="MyThing">

    </mapped-superclass>
</entity-mappings>

Nothing else. If you want to override a property, use @AttributeOverride as shown above