2011-01-08 8 views
5

¿Alguien sabe si es posible establecer una referencia posterior desde dentro de un JPA @EmbeddedId?Cómo establecer una referencia inversa desde @EmbeddedId en JPA

Así, por ejemplo, hay una entidad del Formulario

@Entity 
public class Entity1 { 
    @Id 
    @GeneratedValue 
    private String identifier; 

    private Entity1 relationToEntity1; 
    //Left out the getters and setters for simplicity 
} 

y una segunda entidad con una identificación incrustado compleja. Una parte de esta segunda entidad es una referencia a su entidad matriz. De este modo:

@Entity 
public class Entity2 { 
    @EmbeddedId private Entity2Identifier id; 
    //Left out the getters and setters for simplicity. 
} 

@Embedabble 
public class Entity2Identifier { 
    private String firstPartOfIdentifier; 
    private Entity1 parent; 
    //Left out the getters and setters for simplicity. 
} 

Cuando trato de guardar una construcción de este tipo a través de la APP (Aplicación es EclipseLink) a una base de datos consigo varias excepciones de la forma:

Exception [EclipseLink-93] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT): 
org.eclipse.persistence.exceptions.DescriptorException 
Exception Description: The table [ENTITY1] is not present in this descriptor. 
Descriptor: RelationalDescriptor(test.Entity2 --> [DatabaseTable(ENTITY2)]) 

¿Alguien se encontró con un problema así y tiene una solución?

Respuesta

4

Lo que está buscando es un Id derivado. Si está utilizando JPA 2.0, entonces lo siguiente funcionará. Realmente no quiere que todo el padre sea parte del PK, solo el PK del padre.

@Entity 
public class Entity1 { 
    @EmbeddedId 
    private ParentId identifier; 

    @OneToOne(mappedBy="relationToEntity1") 
    private Entity2 relationToEntity2; 

    //Left out the getters and setters for simplicity 
} 

@Entity 
public class Entity2 { 
    @EmbeddedId private Entity2Identifier id; 
    //Left out the getters and setters for simplicity. 

    @MapsId("parentId") 
    @OneToOne 
    private Entity1 parent; 

} 

@Embedabble 
public class Entity2Identifier { 
    private String firstPartOfIdentifier; 
    private ParentId parentId; 
    //Left out the getters and setters for simplicity. 
} 
+0

OK. Creo que mi ejemplo fue simple. El padre en realidad tiene un ID embebido complejo, que consta de dos cadenas, también. Es por eso que no puedo simplemente hacer referencia a su ID. – ali

+1

Eso es simple también. He actualizado mi ejemplo anterior para usar un EmbeddedId en la Entidad 1. –

+1

¡@MapsId es el ganador! Tan útil. –

1

La anotación @EmbeddedId no permite las relaciones en la clase de identidad compuesta. Desde EmbeddedId JavaDoc:

Las asignaciones de relaciones definidas dentro de una clase de identificación incrustada no son compatibles.

entiendo que desea Entity2Identifier para contener la clave para los padres, pero en su ejemplo, se está creando una relación de todo el objeto en lugar de simplemente incluyendo la clave principal de la matriz. Incluso si esta construcción funcionara, estaría estableciendo que la clave compuesta no es solo la clave principal del padre, sino el estado completo del padre.

Si usted está buscando simplemente una manera fácil de establecer relaciones bi-direccionales, puede hacerlo con la anotación de la @OneToOne y el atributo mappedBy:

@Entity 
public class Entity1 { 
    @Id 
    @GeneratedValue 
    private String identifier; 

    @OneToOne(mappedBy="relationToEntity1") 
    private Entity2 relationToEntity2; 
    ... 
} 

@Entity 
public class Entity2 { 

    @OneToOne 
    private Entity1 relationToEntity1; 
    ... 
} 

Con este conjunto de anotaciones, la APP el proveedor manejará Entity1.relationToEntity2 y Entity2.relationToEntity1 correctamente como una relación bidireccional. También es posible que desee anular el comportamiento de cascada predeterminado (ninguno) así como el comportamiento de eliminación huérfano predeterminado (ninguno). Vea el JavaDoc para más detalles.

+0

Gracias por su respuesta. En realidad, lo sé. El problema es que mi clave principal consta de varias partes, una de las cuales es la entidad principal. Esto significa que hay algún valor que define la entidad, pero solo es válido en el contexto del padre. – ali

Cuestiones relacionadas