Avec Eclipselink/JPA, je peux avoir un Étrangères Clé Composite actions d'un champ avec une première Clé Composite?
Ma base de données dispose de deux entités, la Société et la Personne. Une Entreprise peut avoir beaucoup de Gens, mais une Personne doit avoir qu'une seule Société. La structure de la table se présente comme suit.
SOCIÉTÉ ---------- propriétaire PK comp_id PK c_name
PERSONNE ---------------- propriétaire PK, FK1 personid PK comp_id FK1 p_fname p_sname
Il a eu pour moi que je pouvais retirer de la PERSONNE.PROPRIÉTAIRE et tirer à travers la clé étrangère; cependant, je ne peux pas faire ce changement sans affecter le code de legs.
J'ai modélisé comme JPA-annoté classes;
@Entity @Table(name = "PERSON") @IdClass(PersonPK.class) public class Personne implémente Serializable { @Id private String propriétaire; @Id private String personid; @ManyToOne @JoinColumns( {@JoinColumn(name = "owner", referencedColumnName = "PROPRIÉTAIRE", insérable = false, pouvant être mis à jour = false), Les annotations @JoinColumn(name = "comp_id", referencedColumnName = "COMP_ID", insérable = true, pouvant être mis à jour = true)}) Société privée de l'entreprise; private String p_fname; private String p_sname; ...et standard des getters/setters... }
@Entity @Table(name = "SOCIÉTÉ") @IdClass(CompanyPK.class) public class Société implémente Serializable { @Id private String propriétaire; @Id private String comp_id; private String c_name; @OneToMany(mappedBy = "société", cascade=CascadeType.TOUTES les) Liste privée des personnes; ...et standard des getters/setters... }
Mon PersonPK et CompanyPK classes ne sont rien de spécial, ils ont juste à servir une structure de holding, propriétaire et le champ ID, et de redéfinir hashCode et equals(o).
So far So good. Je tombe sur un problème, cependant, en essayant de traiter avec les associations. Il semble, si j'ai une Société existante, et de créer une Personne, et de les associer à la Personne à la Société et à la persistance de l'entreprise, l'association n'est pas enregistrée lorsque la Personne est insérée. Par exemple, le principal de mon code ressemble à ceci:
EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); CompanyPK companyPK = new CompanyPK(); companyPK.propriétaire="etats-unis"; companyPK.comp_id="1102F3"; Société = em.trouver(Company.class, companyPK); Personne personne = new Personne(); personne.setOwner("états-unis"); personne.setPersonid("5116628123"); //un nombre qui n'existe pas encore personne.setP_fname("Hannah"); personne.setP_sname("Montana"); personne.setCompany(la société); em.persist(personne);
Cela se termine sans erreur; cependant, dans la base de données, je trouve que l'enregistrement de Personne a été inséré avec une valeur null dans le COMP_ID champ. Avec EclipseLink de l'enregistrement de débogage mis à l'AMENDE, la requête SQL est indiqué que:
INSERT INTO PERSONNE (PERSONID,PROPRIÉTAIRE,P_SNAME,P_FNAME) VALUES (?,?,?,?) bind => [5116628123,etats-unis,dans le Montana,Hannah,]
Je me serais attendu à ce pour être sauvé, et que la requête soit l'équivalent de
INSERT INTO PERSONNE (PERSONID,PROPRIÉTAIRE,COMP_ID,P_SNAME,P_FNAME) VALEURS (?,?,?,?,?) bind => [5116628123,etats-unis,1102F3,Montana,Hannah,]
Ce qui donne? Est-il inexact de dire pouvant être mis à jour/insérable=true pour la moitié d'une clé composite et =false pour l'autre moitié? Si j'ai mis à jour/insérable=true pour les deux parties de la clé étrangère, puis Eclipselink ne parvient pas à un démarrage en disant que je ne peux pas utiliser la colonne deux fois sans avoir une valeur readonly par la spécification de ces options.
OriginalL'auteur user107924 | 2009-07-08
Vous devez vous connecter pour publier un commentaire.
Votre code devrait fonctionner. Vous assurer que vous recompilé/déployé correctement.
Quelle version utilisez-vous?
Également veiller à ce que votre Entreprise objet de la validité de l'id défini.
Vous pouvez également essayer de mettre ,
propriétaire du champ @Colonne et de laisser la totalité de la clé étrangère insérable/mise à jour.
OriginalL'auteur James
J'ai eu le même problème. Et la solution que j'ai trouvé est de anotate champs de clé primaire non insérable et non modifiable. Votre personne entité devrait ressembler à ceci:
OriginalL'auteur
Le chemin que j'ai fait c'était pour annoter les champs de la PK de la classe comme j'aurais si ils étaient sur l'entité.
Puis dans l'entité n'ont pas les champs de la PK classe contient. Si vous voulez vous pouvez mettre en œuvre les méthodes de lecture que passthrough
La PersonPK doit être sérialisable et annotée
@Embeddable
OriginalL'auteur harmanjd
En dehors de la conception de bases de données étant plutôt bizarre, cela peut fonctionner:
OriginalL'auteur siebz0r