J'ai une table qui ne contient que 2 champs. La table a une PK composite formée par ces deux champs.
Lors de l'utilisation de Netbeans pour créer des beans entité à partir d'une base de données, le bean entité n'est pas créé automatiquement comme les autres tables comportant plus de 2 champs.
Je suppose donc que je dois créer le bean entité moi-même. Quelle est la meilleure pratique pour créer ce bean entité? Doit-il contenir un objet COMPOSITE KEY
ou non?
Je n'utilise pas NetBeans, je ne peux donc rien en dire sur ses outils de cartographie.
Pour mapper une clé composite, il existe deux options. Vous pouvez
Définissez un objet @Embeddable
séparé avec les champs PK et utilisez-le comme @EmbeddedId
dans votre classe @Entity
@Embeddable
public class MyCompositePK {
@Column
private String fieldA;
@Column
private String fieldB;
}
@Entity
public class MyBean {
@EmbeddedId
private MyCompositePK id;
@Column
private String fieldC;
}
Définissez un POJO non mappé avec les champs PK et utilisez-le comme @IdClass
dans le @Entity
.
@Entity
@IdClass(value=ClassAB.ClassABId.class)
public class ClassAB implements Serializable {
private String idA;
private String idB;
@Id
@Column(name="ID_A")
public String getIdA(){ return idA; }
public void setIdA(String idA){ this.idA = idA; }
@Id
@Column(name="ID_B")
public String getIdB(){ return idB; }
public void setIdB(String idB){ this.idB = idB; }
static class ClassABId implements Serializable {
private String idA;
private String idB;
public String getIdA(){ return idA; }
public void setIdA(String idA){ this.idA = idA; }
public String getIdB(){ return idB; }
public void setIdB(String idB){ this.idB = idB; }
// implement equals(), hashcode()
}
}
Dans cet exemple, ClassABId
est une classe interne statique uniquement pour des raisons de commodité.
Ces options sont également expliquées dans l'excellente réponse de Pascal Thivent à cette question: Comment mapper une clé composite avec Hibernate? .
Cette question connexe traite des différences entre ces approches: Quelle annotation dois-je utiliser: @IdClass ou @EmbeddedId . Notez que la déclaration des champs est dupliquée avec l'approche @IdClass
.
Quoi qu'il en soit, je ne pense pas qu'il existe une alternative à la création de deux classes. C'est pourquoi j'ai posé la question suivante: Mappage d'une classe composée uniquement d'une PK composite sans @IdClass ou @EmbeddedId . Il semble qu'il existe une fonctionnalité spécifique à l'hibernation pour cela.
Remarque: si vous avez le contrôle de la structure de la base de données, vous pouvez également envisager d'éviter les clés composites. Il y a quelques raisons de le faire .
Merci @ XaviLópez. Votre explication a corrigé mon code qui a été déclaré comme étant sa propre IdClass mentionnée par @Tom Anderson. Lorsque j'ai déclaré que sa propre classe IdClass avait 2 colonnes @ Id, une requête JPA extraire une liste de cette entité renvoyait les éléments "n" attendus dans la liste des résultats, mais chaque élément de cette liste est null. Mais cette taille "n" est attendue. Après être passé à la classe interne statique, ce qui est moins le refactoring, il est capable de retourner le bon jeu de résultats.
Selon moi: l'auto-référencement IdClass ne fonctionnera pas car le moi est déjà une entité et doit être en contexte de persistance. Si j'ai aussi un objet de clé primaire du même type, il y aura deux objets "identiques" dans le contexte de persistance. Donc, cela ne devrait pas être autorisé. Par conséquent, nous ne devrions pas utiliser l'auto-référencement @IdClass. Créez une classe interne statique en tant que type de clé primaire moins intrusive.