2011-01-08 5 views
5

Weiß jemand, ob es möglich ist, eine Rückreferenz innerhalb einer JPA @EmbeddedId zu erstellen.So stellen Sie eine Rückreferenz von einer @EmbeddedId in JPA ein

So gibt es zum Beispiel ein Entity des Formulars

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

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

Und eine zweite Einheit mit einem komplexen eingebetteten Id. Ein Teil dieser zweiten Entität ist eine Referenz auf ihre Muttergesellschaft. Wie so:

@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. 
} 

Wenn ich versuche, ein solches Konstrukt über JPA zu speichern (Implementation ist Eclipse) in einer Datenbank erhalte ich mehrere Ausnahmen von der Form:

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)]) 

Hat jemand auf ein solches Problem gestoßen und hat eine Lösung?

Antwort

4

Was Sie suchen, ist eine abgeleitete ID. Wenn Sie JPA 2.0 verwenden, funktioniert Folgendes. Du willst wirklich nicht, dass das ganze Elternteil ein Teil des PK ist, nur der PK der Eltern.

@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. Ich denke, mein Beispiel war zu einfach. Der Elternteil hat tatsächlich eine komplexe eingebettete ID, die ebenfalls aus zwei Strings besteht. Deshalb kann ich nicht einfach auf seine ID verweisen. – ali

+1

Das ist auch einfach. Ich habe mein Beispiel aktualisiert, um eine EmbeddedId auf Entität 1 zu verwenden. –

+1

@MapsId ist der Gewinner! So nützlich. –

1

Die Annotation @EmbeddedId lässt keine Beziehungen in der zusammengesetzten Identitätsklasse zu. Von der :

Beziehungszuordnungen, die in einer eingebetteten ID-Klasse definiert sind, werden nicht unterstützt.

Ich verstehe, dass Sie Entity2Identifier wollen den Schlüssel für die Eltern enthalten, aber in Ihrem Beispiel sind Sie eine Beziehung auf das gesamte Objekt zu schaffen, anstatt nur den Primärschlüssel des Mutter einschließlich. Selbst wenn diese Konstruktion funktionierte, würden Sie feststellen, dass der zusammengesetzte Schlüssel nicht nur der Primärschlüssel des Elternteils ist, sondern der gesamte Status des Elternteils.

Wenn Sie sich einfach für eine einfache Möglichkeit suchen bidirektionale Beziehungen aufzubauen, können Sie dies mit dem der @OneToOne Annotation und das mappedBy Attribut:

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

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

@Entity 
public class Entity2 { 

    @OneToOne 
    private Entity1 relationToEntity1; 
    ... 
} 

Mit diesem Satz von Anmerkungen, die JPA Anbieter wird Entity1.relationToEntity2 und Entity2.relationToEntity1 ordnungsgemäß als eine bidirektionale Beziehung behandeln. Möglicherweise möchten Sie auch das standardmäßige Kaskadenverhalten (keine) sowie das standardmäßige Verhalten zum Entfernen von verwaisten Objekten (keine) außer Kraft setzen. Weitere Details finden Sie unter JavaDoc.

+0

Danke für Ihre Antwort. Eigentlich kenne ich das. Das Problem besteht darin, dass mein Primärschlüssel aus mehreren Teilen besteht, von denen einer die übergeordnete Entität ist. Dies bedeutet, dass ein Wert vorhanden ist, der die Entität definiert, aber nur im Kontext des übergeordneten Elements gültig ist. – ali