2010-03-25 14 views
49

Digamos que tengo el siguiente POJO:¿Es posible construir una entidad JPA extendiendo un POJO?

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

¿Es ahora posible extender este POJO como una entidad JPA?

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

Quiero mantener el POJO separado de la entidad JPA. El POJO vive en un proyecto diferente y a menudo se utiliza sin una capa de persistencia, mi proyecto quiere persistir en una base de datos y hacerlo sin la sobrecarga de la asignación de un POJO a una entidad y viceversa.

Entiendo que las entidades JPA son POJO, pero para usarlo tendría que incluir una biblioteca que implemente javax.persistence y los otros proyectos que usen el mismo objeto base no tengan uso para una capa de persistencia.

¿Esto es posible? ¿Es esta una buena idea?

Respuesta

63

especificación JPA afirma

Entidades pueden extenderse clases no entidad, así como clases de entidad, y clases de no-entidad pueden extender las clases de entidad.

@ javax.persistence.MappedSuperclass anotación le permite definir este tipo de mapeo

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

    // getter's and setter's 
} 

Y

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


} 

Según lo dicho por la especificación JPA

La anotación MappedSuperclass designa una clase cuya información de mapeo se aplica a las entidades que heredan de ella.

Y

Una clase designada con la anotación MappedSuperclass se puede asignar de la misma manera como una entidad excepto que las asignaciones se aplicarán únicamente a sus subclases ya que no existe la tabla de la superclase asignada sí mismo.

Si necesita reemplazar alguna propiedad definida por MYTHing, utilice @AttributeOverride (cuando se desea anular una sola propiedad) o @AttributeOverrides (cuando se desea anular más de una propiedad)

@Entity 
@Table(name="MY_THING") 
@AttributeOverride(name="myData", [email protected](name="MY_DATA")) 
public class MyThingEntity extends MyThing { 


} 

Y

@Entity 
@Table(name="MY_OTHER_THING") 
@AttributeOverrides({ 
    @AttributeOverride(name="myData1", [email protected](name="MY_DATA_1")), 
    @AttributeOverride(name="myData2", [email protected](name="MY_DATA_2")) 
}) 
public class MyOtherThingEntity extends MyThing { 

} 

Si no desea cambiar su clase base, puede utilizar XML para definirla como una @MappedSuperclass

Tenga en cuenta: por defecto, el proveedor de persistencia buscará en el directorio META-INF para un orm.xml llamado

<?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> 

Nada más archivo. Si desea anular una propiedad, use @AttributeOverride como se muestra arriba

+2

sospecho que la idea es no cambiar la clase MyThing –

+1

Maxime es correcto, no quiero tocar el POJO base. Todavía podría funcionar, '@MappedSuperclass MyThingMapper extiende MyThing .... MyThingEntity extends MyThingWrapper' – Freiheit

+0

@Freiheit Agregado a la respuesta original –

6

Es posible:

  • puede asignar con XML - crea un orm.xml (conforme a la orm schema) y el mapa de las columnas de su POJO, sin ni siquiera extenderlo. Será JPA-habilitado en un medio ambiente y un POJO en el otro
  • anulación sólo los métodos getter y les anotar - (no estoy seguro de si esto va a funcionar)

Dicho esto, no creo que sea necesario hacer esto. Simplemente haga una anotación en su POJO y agregue la dependencia en tiempo de compilación a sus proyectos. Luego, cada proyecto decidirá si los usará como entidades JPA o no.

+0

Tenga en cuenta que debe encontrar una manera de darse cuenta cuando se cambia el POJO para que pueda cambiar su archivo de mapeo. –

+0

Supongamos por ahora que el equipo que ejecuta el proyecto que tiene el POJO no me permitirá en ningún caso enviar un parche con las anotaciones JPA y una importación javax.persistence. ¿Existe una biblioteca javax.persistence "ficticia" por lo que la importación funciona, pero no es necesario arrastrar los archivos JAR de EclipseLink si no se desea la persistencia? – Freiheit

+1

Las anotaciones por sí solas no causarán un problema de tiempo de ejecución incluso si el contenedor que las contiene no está presente. Todavía sería necesario en tiempo de compilación. No estoy seguro de dónde más está disponible, pero Maven tiene un javax.persistence-persistence-api-1.0.jar en el repositorio (http://mvnrepository.com/artifact/javax.persistence/persistence-api/1.0) . – ColinD

Cuestiones relacionadas