Ich halte das @EmbeddedId
wahrscheinlich für ausführlicher, da @IdClass
Sie mit keinem Feldzugriffsoperator auf das gesamte Primärschlüsselobjekt zugreifen können. Mit dem können @EmbeddedId
Sie Folgendes tun:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Dies gibt eine klare Vorstellung von den Feldern, aus denen der zusammengesetzte Schlüssel besteht, da sie alle in einer Klasse zusammengefasst sind, auf die über einen Feldzugriffsoperator zugegriffen wird.
Ein weiterer Unterschied zu @IdClass
und @EmbeddedId
ist, wenn es darum geht, HQL zu schreiben:
Mit @IdClass
dir schreiben:
Wählen Sie e.name aus Mitarbeiter e
und mit @EmbeddedId
dir muss schreiben:
Wählen Sie e.employeeId.name aus Employee e
Sie müssen mehr Text für dieselbe Abfrage schreiben. Einige mögen argumentieren, dass sich dies von einer natürlicheren Sprache wie der von unterscheidet IdClass
. In den meisten Fällen ist es jedoch von unschätzbarem Wert, direkt anhand der Abfrage zu verstehen, dass ein bestimmtes Feld Teil des zusammengesetzten Schlüssels ist.
@IdClass
auch wenn ich dies@EmbeddedId
in den meisten Situationen bevorzuge ( Ich habe dies aus einer Sitzung von Antonio Goncalves erfahren. Er schlug vor, dass wir den@IdClass
Fall für den Fall des Komposits verwenden könnten Schlüsselklasse ist nicht zugänglich oder kommt von einem anderen Modul oder Legacy-Code, wo wir keine Annotation hinzufügen können. In diesen Szenarien@IdClass
geben uns einen Weg unsere.@IdClass
von @Gaurav angegebenen Annotation genau der Grund sind, warum die JPA-Spezifikation beide Methoden zum Erstellen eines zusammengesetzten Schlüssels@IdClass
@EmbeddidId
Es gibt drei Strategien zur Verwendung eines zusammengesetzten Primärschlüssels:
@Embeddable
und fügen Sie Ihrer Entitätsklasse eine normale Eigenschaft hinzu, die mit markiert ist@Id
.@EmbeddedId
.@Id
und markieren Sie Ihre Entitätsklasse mit@IdClass
, indem Sie die Klasse Ihrer Primärschlüsselklasse angeben.Die Verwendung
@Id
mit einer Klasse, die als markiert@Embeddable
ist, ist der natürlichste Ansatz. Das@Embeddable
Tag kann ohnehin für nicht in Primärschlüssel einbettbare Werte verwendet werden. Sie können den zusammengesetzten Primärschlüssel als eine einzelne Eigenschaft behandeln und die@Embeddable
Klasse in anderen Tabellen wiederverwenden .Der nächst natürlichste Ansatz ist die Verwendung des
@EmbeddedId
Tags. Hier kann die Primärschlüsselklasse nicht in anderen Tabellen verwendet werden, da es sich nicht um eine@Embeddable
Entität handelt. Sie ermöglicht es uns jedoch, den Schlüssel als einzelnes Attribut einer Klasse zu behandeln.Schließlich ermöglicht die Verwendung der Annotationen
@IdClass
und die@Id
Annotation der zusammengesetzten Primärschlüsselklasse unter Verwendung der Eigenschaften der Entität selbst, die den Namen der Eigenschaften in der Primärschlüsselklasse entsprechen. Die Namen müssen übereinstimmen (es gibt keinen Mechanismus, um dies zu überschreiben), und die Primärschlüsselklasse muss die gleichen Verpflichtungen wie bei den beiden anderen Techniken erfüllen. Der einzige Vorteil dieses Ansatzes ist seine Fähigkeit, die Verwendung der Primärschlüsselklasse vor der Schnittstelle der einschließenden Entität zu "verbergen". Die@IdClass
Annotation verwendet einen Wertparameter vom Typ Klasse, der die Klasse sein muss, die als zusammengesetzter Primärschlüssel verwendet werden soll. Die Felder, die den Eigenschaften der zu verwendenden Primärschlüsselklasse entsprechen, müssen alle mit Anmerkungen versehen sein@Id
.Referenz: http://www.apress.com/us/book/9781430228509
quelle
Ich habe eine Instanz entdeckt, in der ich EmbeddedId anstelle von IdClass verwenden musste. In diesem Szenario gibt es eine Verknüpfungstabelle, in der zusätzliche Spalten definiert sind. Ich habe versucht, dieses Problem mithilfe von IdClass zu lösen, um den Schlüssel einer Entität darzustellen, die explizit Zeilen in der Join-Tabelle darstellt. Ich konnte es nicht so zum Laufen bringen. Zum Glück hat "Java Persistence With Hibernate" einen Abschnitt, der diesem Thema gewidmet ist. Eine vorgeschlagene Lösung war meiner sehr ähnlich, verwendete jedoch stattdessen EmbeddedId. Ich habe meine Objekte nach denen im Buch modelliert, die sich jetzt korrekt verhalten.
quelle
Soweit ich weiß, ist es einfacher und unkomplizierter, wenn Ihre zusammengesetzte PK FK enthält
@IdClass
Mit müssen
@EmbeddedId
Sie die Zuordnung für Ihre FK-Spalte zweimal definieren, einmal@Embeddedable
und einmal für, dh@ManyToOne
wo@ManyToOne
muss schreibgeschützt sein (@PrimaryKeyJoinColumn
), da Sie nicht eine Spalte in zwei Variablen festlegen können (mögliche Konflikte).Sie müssen also Ihre FK durch einfaches Eingeben einstellen
@Embeddedable
.Auf der anderen Site kann die Verwendung
@IdClass
dieser Situation viel einfacher gehandhabt werden, wie in Primärschlüssel über OneToOne- und ManyToOne-Beziehungen gezeigt :Beispiel für eine JPA 2.0 ManyToOne-ID-Annotation
Beispiel für eine JPA 2.0-ID-Klasse
quelle
Ich denke, der Hauptvorteil ist, dass wir
@GeneratedValue
für die ID verwenden könnten, wenn wir das@IdClass
? Ich bin sicher, wir können nicht@GeneratedValue
für verwenden@EmbeddedId
.quelle
Der zusammengesetzte Schlüssel darf bei Verwendung keine
@Id
Eigenschaft haben@EmbeddedId
.quelle
Mit EmbeddedId können Sie die IN-Klausel in HQL verwenden, zum Beispiel:
FROM Entity WHERE id IN :ids
wobei id eine EmbeddedId ist, während es schwierig ist, mit IdClass dasselbe Ergebnis zu erzielen, wie Sie es möchtenFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN
quelle