使用Eclipselink/JPA,我可以拥有一个与主复合密钥共享一个字段的外复合密钥吗? [英] With Eclipselink/JPA, can I have a Foreign Composite Key that shares a field with a Primary Composite Key?

查看:64
本文介绍了使用Eclipselink/JPA,我可以拥有一个与主复合密钥共享一个字段的外复合密钥吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据库有两个实体;公司和人员.一个公司可以有很多人,但是一个人只能有一个公司.表结构如下所示.

My database has two entities; Company and Person. A Company can have many People, but a Person must have only one Company. The table structure looks as follows.

COMPANY
----------
owner   PK
comp_id PK
c_name

PERSON
----------------
owner    PK, FK1
personid PK
comp_id  FK1
p_fname
p_sname

我想到可以删除PERSON.OWNER并通过外键派生它;但是,我不能在不影响旧代码的情况下进行此更改.

It has occurred to me that I could remove PERSON.OWNER and derive it through the foreign key; however, I can't make this change without affecting legacy code.

我已将这些模型建模为JPA注释的类;

I have modeled these as JPA-annotated classes;

@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).

My PersonPK and CompanyPK classes are nothing special, they just serve as a struct holding owner and the ID field, and override hashCode and equals(o).

到目前为止,一切都很好.但是,在尝试处理关联时遇到一个问题.看来,如果我有一个现有公司,并创建一个Person,并将其与该公司关联到该公司并保留该公司,则在插入Person时不会保存该关联.例如,我的主要代码如下:

So far so good. I come across a problem, however, when trying to deal with associations. It seems if I have an existing Company, and create a Person, and associate to the Person to the Company and persist the company, the association is not saved when the Person is inserted. For example, my main code looks like this:

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查询显示为:

This completes without error; however in the database I find that the Person record was inserted with a null in the COMP_ID field. With EclipseLink debug logging set to FINE, the SQL query is shown as:

INSERT INTO PERSON (PERSONID,OWNER,P_SNAME,P_FNAME) VALUES (?,?,?,?)
  bind => [5116628123,USA,Montana,Hannah,]

我希望它会被保存,并且查询等同于

I would have expected this to be saved, and the query to be equivalent to

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无法启动,说我不能通过两次使用该列,除非通过指定这些选项将其设置为只读.

What gives? Is it incorrect to say updatable/insertable=true for one half of a composite key and =false for the other half? If I have updatable/insertable=true for both parts of the foreign key, then Eclipselink fails to startup saying that I can not use the column twice without having one set to readonly by specifying these options.

推荐答案

您的代码应该可以工作.确保正确地重新编译/部署了它. 您使用的是什么版本?

Your code should work. Ensure you recompiled/deployed it correctly. What version are you using?

还要确保您的Company对象具有有效的ID集.

Also ensure that your Company object has a valid id set.

您也可以尝试放置,

insertable = false, updatable = false

在所有者字段的@Column中,并保留整个可插入/可更新的外键.

in your owner field's @Column and leave the entire foreign key insertable/updatable.

这篇关于使用Eclipselink/JPA,我可以拥有一个与主复合密钥共享一个字段的外复合密钥吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆