使用@JoinColumn进行@OneToOne双向映射

时间:2012-05-21 14:48:46

标签: hibernate primary-key one-to-one

假设我有人

class Person{
    @Id Integer id;

    @OneToOne
    @JoinColumn(name = "person_id")
    Job myJob;
}

和工作

class Job{
    @Id Integer id;
    Integer person_id;

    @OneToOne
    @PrimaryKeyJoinColumn(name = "person_id")
    Person currentWorker;
}

提取时,我无法将人员和工作映射到其他实体 我在做什么错误?

2 个答案:

答案 0 :(得分:8)

您的代码应为:

@Entity
public class Person implements Serializable {

    @Id Integer id;

    @OneToOne
    @JoinColumn(name = "id")
    Job myJob;
}

@Entity
public class Job implements Serializable {

    @Id Integer id;

    @OneToOne(mappedBy = "myJob")
    Person currentWorker;
}  

(注意从Job删除重复列'person_id')

或其他共享主键的方法:

@Entity
public class Person {
    @Id Integer id;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    Job myJob;
}            

@Entity
public class Job {
    @Id Integer id;
} 

答案 1 :(得分:0)

本讨论假定某个属性如"更新"被分配给persistence.xml中的hibernate.hbm2ddl.auto,以使Hibernate能够建立一对一关系并在拥有实体中为非拥有实体创建外键,并在相应的外键中创建外键。表。但是,只有在创建表时建立关系,此过程才会成功。将@JoinColumn和@OneToOne(mappedBy)添加到现有实体将导致Hibernate抱怨FK列不存在于拥有表中。因此,在实现包含实时数据的表之间的关系时,需要手动添加FK列。然后,Hibernate将能够使用奇怪的名称建立FK约束,如FKg6wt3d1u6o13gdc1hj36ad1ot。

所涉及的细微差别通过稍微更详细的例子来说明。考虑一个数据库,其中实体Contact将是加入OneToOne的各种表(员工,客户,供应商等)的通用组件。作为初步考虑,虽然OneToOne关系可以是双向的,但是它在Hibernate中的实现规定公共实体被分配非拥有指定,以便在每个拥有实体的表中创建FK。反过来实现OneToOne将导致Hibernate在NON-owning类中查找外键并在找不到时抛出错误。 (在那里,做到了。)

@Entity // common, non-owning entity
public class Contact implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)

private Integer id;

    @Column(name="fn")
    private String firstName;

    @Column(name="ln")
    private String lastName;

// "person" is the Contact entity as declared in Director
  @OneToOne(optional=false, mappedBy = "person")    
  private Director director;

 // GETTERS & SETTERS

@Entity // owning entity
public class Director implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)

private Integer id;

    @Column(name="title")
    private String title;

@OneToOne
    @JoinColumn
    private Contact person;

public Integer getId() {
        return id;
}   
public String getTitle() {
        return title;
}
public void setTitle(String title) {
        this.title = title;
}
public Contact getPerson() {
        return person;
}
public void setPerson(Contact person) {
        this.person = person;
}

假设Director中存在FK列,代码将生成:

alter table Director 
   add constraint FKg6wt3d1u6o13gdc1hj36ad1ot 
   foreign key (person_id) 
   references Contact (id)

FK名称Hibernate在Director中分配给Contact实体的推导有点模糊。它是分配给拥有实体(此处为人)中的Contact实例变量的变量名的串联+" _" +实体的主键" id,"产生person_id。另请注意,@ OneToOne(mappedBy =" person")注释引用了同一个Contact实例变量。最后,Hibernate直接访问FK列,而无需在Director类中使用相应的getter和setter。