Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

jpa

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?

like image 726
Freiheit Avatar asked Mar 25 '10 14:03

Freiheit


People also ask

Is JPA entity a POJO?

Entity. Entities in JPA are nothing but POJOs representing data that can be persisted to the database. An entity represents a table stored in a database. Every instance of an entity represents a row in the table.

What is pojo in JPA?

To be able to store Point objects in the database using JPA we need to define an entity class. A JPA entity class is a POJO (Plain Old Java Object) class, i.e. an ordinary Java class that is marked (annotated) as having the ability to represent objects in the database.

Can we extend entity class in Java?

Entities support class inheritance, polymorphic associations, and polymorphic queries. Entity classes can extend non-entity classes, and non-entity classes can extend entity classes. Entity classes can be both abstract and concrete.

What will happen if @table is not specified while defining pojo?

If no @Table is defined the default values are used: the unqualified class name of the entity. For example if you have: @Entity public class MyTest{ ... Your table will have the name my_test in your database.


2 Answers

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 @AttributeOverride (when you want to override a single property) or @AttributeOverrides (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 {   } 

And

@Entity @Table(name="MY_OTHER_THING") @AttributeOverrides({     @AttributeOverride(name="myData1", column=@Column(name="MY_DATA_1")),     @AttributeOverride(name="myData2", column=@Column(name="MY_DATA_2")) }) public class MyOtherThingEntity 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

like image 154
Arthur Ronald Avatar answered Sep 19 '22 11:09

Arthur Ronald


It is possible:

  • you can map it with XML - make an orm.xml (conforming to the orm schema), and map the columns of your POJO, without even extending it. It will be JPA-enabled in one environment, and a POJO in the other one
  • override just the getter methods and annotate them - (I'm not sure if this will work)

That said, I don't think it is necessary to do this. Just annotate your POJO, and add the compile-time dependency to your projects. Then each project will decide whether it will use them as JPA entities or not.

like image 37
Bozho Avatar answered Sep 21 '22 11:09

Bozho