私のデータベースには2つのエンティティがあります。会社と人。会社は多くの人を持つことができますが、人は会社を1つしか持たないことが必要です。表の構造は次のようになります。Eclipselink/JPAでは、プライマリコンポジットキーとフィールドを共有する外部コンポジットキーを使用できますか?
COMPANY ---------- owner PK comp_id PK c_name
PERSON ---------------- owner PK, FK1 personid PK comp_id FK1 p_fname p_sname
私がPERSON.OWNERを削除し、外部キーを通してそれを引き出すことができることを私に発生しました。しかし、私はレガシーコードに影響を与えずにこの変更を行うことはできません。
私はこれをJPAアノテーション付きクラスとしてモデル化しました。
@Entity @Table(name = "PERSON") @IdClass(PersonPK.class) public class Person implements Serializable { @Id private String owner; @Id private String personid; @ManyToOne @JoinColumns( {@JoinColumn(name = "owner", referencedColumnName = "OWNER", insertable = false, updatable = false), @JoinColumn(name = "comp_id", referencedColumnName = "COMP_ID", insertable = true, updatable = true)}) private Company company; private String p_fname; private String p_sname; ...and standard getters/setters... }
@Entity @Table(name = "COMPANY") @IdClass(CompanyPK.class) public class Company implements Serializable { @Id private String owner; @Id private String comp_id; private String c_name; @OneToMany(mappedBy = "company", cascade=CascadeType.ALL) private List people; ...and standard getters/setters... }
マイPersonPKとCompanyPKクラスは何も特別ではない、彼らは単に構造体保持所有者とIDフィールドとして働き、とhashCodeとequals(O)をオーバーライドします。
これまでのところとても良いです。しかし、私は問題に直面しています。私が既存の会社を持っていてPersonを作って、そのPersonとCompanyに関連させて会社を存続させると、その人物が挿入されたときには、その関連は保存されません。たとえば、私のメインコードは次のようになります:
EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); CompanyPK companyPK = new CompanyPK(); companyPK.owner="USA"; companyPK.comp_id="1102F3"; Company company = em.find(Company.class, companyPK); Person person = new Person(); person.setOwner("USA"); person.setPersonid("5116628123"); //some number that doesn't exist yet person.setP_fname("Hannah"); person.setP_sname("Montana"); person.setCompany(company); em.persist(person);
これでエラーはなくなります。データベースでは、COMP_IDフィールドにPersonレコードがnullで挿入されていました。 FINEへのEclipseLinkデバッグログを設定すると、SQLクエリは次のように示されている:
INSERT INTO PERSON (PERSONID,OWNER,P_SNAME,P_FNAME) VALUES (?,?,?,?) bind => [5116628123,USA,Montana,Hannah,]
私は、これが保存されると予想しているだろう、とクエリが与え何
INSERT INTO PERSON (PERSONID,OWNER,COMP_ID,P_SNAME,P_FNAME) VALUES (?,?,?,?,?) bind => [5116628123,USA,1102F3,Montana,Hannah,]
に相当すると?コンポジットキーの半分にupdatable/insertable = trueを、残りの半分に= falseと言うのは間違っていますか?外部キーの両方の部分に対してupdatable/insertable = trueを指定した場合、Eclipselinkは、これらのオプションを指定して読み取り専用に設定しなくても、列を2度使用できないことを示す起動に失敗します。
あなたは手の込んだてもらえますか?これを行うことの効果は何ですか?どの段階で、所有者の属性にその値が設定されているとしますか? – djna