我的数据库有两个实体;公司和个人。一个公司可以有很多人,但一个人只能有一个公司。表结构如下所示。使用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)。
到目前为止这么好。然而,当我试图对付社团时,我遇到了一个问题。看起来,如果我拥有一个现有公司并创建一个人,并将该人员关联到该公司并坚持该公司,则该人员插入时该关联不会被保存。例如,我的主代码如下所示:
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);
完成时没有错误;但是在数据库中,我发现Person记录在COMP_ID字段中插入了一个空值。随着EclipseLink的调试日志记录设置为FINE,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无法启动,说我不能通过指定这些选项来使用列两次,而没有一次设置为只读。
你能否详细说明?这样做的效果是什么? (比方说)所有者属性在什么阶段被赋值? – djna 2011-07-08 07:19:43