Je considère que @EmbeddedId
c'est probablement plus détaillé car avec @IdClass
vous ne pouvez pas accéder à l'ensemble de l'objet clé primaire en utilisant un opérateur d'accès au champ. En utilisant le, @EmbeddedId
vous pouvez faire comme ceci:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Cela donne une notion claire des champs qui composent la clé composite car ils sont tous agrégés dans une classe accessible via un opérateur d'accès aux champs.
Une autre différence avec @IdClass
et @EmbeddedId
est quand il s'agit d'écrire HQL:
Avec @IdClass
vous écrivez:
sélectionnez e.name dans Employee e
et avec @EmbeddedId
vous devez écrire:
sélectionnez e.employeeId.name dans Employee e
Vous devez écrire plus de texte pour la même requête. Certains peuvent argumenter que cela diffère d'un langage plus naturel comme celui promu par IdClass
. Mais la plupart du temps, comprendre dès la requête qu'un champ donné fait partie de la clé composite est d'une aide précieuse.
@IdClass
même si je préfère@EmbeddedId
dans la plupart des situations ( Je dois le savoir à partir d'une session d'Antonio Goncalves. Ce qu'il a suggéré, c'est que nous pourrions utiliser le@IdClass
dans le cas où le composite la classe de clé n'est pas accessible ou provient d'un autre module ou d'un code hérité où nous ne pouvons pas ajouter d'annotation .Dans ces scénarios@IdClass
, nous allons nous donner un moyen de notre.@IdClass
annotation donnée par @Gaurav soient la raison même pour laquelle la spécification JPA répertorie les deux méthodes de création d'une clé composite ..@IdClass
et@EmbeddidId
Il existe trois stratégies pour utiliser une clé primaire composée:
@Embeddable
et ajoutez à votre classe d'entité une propriété normale, marquée par@Id
.@EmbeddedId
.@Id
et marquez votre classe d'entité avec@IdClass
, en fournissant la classe de votre classe de clé primaire.L'utilisation de
@Id
avec une classe marquée comme@Embeddable
étant l'approche la plus naturelle. La@Embeddable
balise peut quand même être utilisée pour les valeurs incorporables de clé non primaire. Il vous permet de traiter la clé primaire composée comme une propriété unique et permet la réutilisation de la@Embeddable
classe dans d'autres tables.La deuxième approche la plus naturelle est l'utilisation de la
@EmbeddedId
balise. Ici, la classe de clé primaire ne peut pas être utilisée dans d'autres tables car ce n'est pas une@Embeddable
entité, mais elle nous permet de traiter la clé comme un attribut unique d'une classe.Enfin, l'utilisation des annotations
@IdClass
et@Id
nous permet de mapper la classe de clé primaire composée en utilisant les propriétés de l'entité elle-même correspondant aux noms des propriétés de la classe de clé primaire. Les noms doivent correspondre (il n'y a pas de mécanisme pour remplacer cela), et la classe de clé primaire doit respecter les mêmes obligations qu'avec les deux autres techniques. Le seul avantage de cette approche est sa capacité à «masquer» l'utilisation de la classe de clé primaire à l'interface de l'entité englobante. L'@IdClass
annotation prend un paramètre de valeur de type Classe, qui doit être la classe à utiliser comme clé primaire composée. Les champs qui correspondent aux propriétés de la classe de clé primaire à utiliser doivent tous être annotés avec@Id
.Référence: http://www.apress.com/us/book/9781430228509
la source
J'ai découvert une instance où je devais utiliser EmbeddedId au lieu d'IdClass. Dans ce scénario, une table de jointure a des colonnes supplémentaires définies. J'ai tenté de résoudre ce problème en utilisant IdClass pour représenter la clé d'une entité qui représente explicitement des lignes dans la table de jointure. Je ne pouvais pas le faire fonctionner de cette façon. Heureusement, "Java Persistence With Hibernate" a une section dédiée à ce sujet. Une solution proposée était très similaire à la mienne, mais elle utilisait EmbeddedId à la place. J'ai modelé mes objets après ceux du livre, ils se comportent maintenant correctement.
la source
Pour autant que je sache, si votre PK composite contient du FK, il est plus facile et plus simple à utiliser
@IdClass
Avec,
@EmbeddedId
vous devez définir le mappage pour votre colonne FK deux fois, une fois dans@Embeddedable
et une fois pour comme c'est-à-dire@ManyToOne
où@ManyToOne
doit être en lecture seule (@PrimaryKeyJoinColumn
) car vous ne pouvez pas avoir une colonne définie dans deux variables (conflits possibles).Vous devez donc définir votre FK en utilisant une saisie simple
@Embeddedable
.Sur l'autre site, l'utilisation de
@IdClass
cette situation peut être traitée beaucoup plus facilement, comme indiqué dans les clés primaires via les relations OneToOne et ManyToOne :Exemple d'annotation d'identifiant ManyToOne JPA 2.0
Exemple de classe d'identifiant JPA 2.0
la source
Je pense que le principal avantage est que nous pourrions utiliser
@GeneratedValue
pour l'identifiant lors de l'utilisation du@IdClass
? Je suis sûr que nous ne pouvons pas utiliser@GeneratedValue
pour@EmbeddedId
.la source
La clé composite ne doit pas avoir de
@Id
propriété lorsqu'elle@EmbeddedId
est utilisée.la source
Avec EmbeddedId, vous pouvez utiliser la clause IN dans HQL, par exemple:
FROM Entity WHERE id IN :ids
où id est un EmbeddedId alors qu'il est difficile d'obtenir le même résultat avec IdClass, vous voudrez faire quelque chose commeFROM Entity WHERE idPartA = :idPartA0 AND idPartB = :idPartB0 .... OR idPartA = :idPartAN AND idPartB = :idPartBN
la source