4

假设我有人

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;
}

获取时,我无法将 Person 和 Job 映射到其他实体。
我在做什么错?

4

2 回答 2

10

您的代码应该是:

@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;
} 
于 2012-05-21T15:06:24.560 回答
1

本讨论假设在 persistence.xml 中为 hibernate.hbm2ddl.auto 分配了诸如“update”之类的属性,以使 Hibernate 能够建立一对一关系并在拥有实体中为非拥有实体创建外键,以及对应表中的外键标识列。但是,只有在创建表时建立了关系,此过程才会成功。将@JoinColumn 和@OneToOne(mappedBy) 添加到现有实体将导致Hibernate 抱怨FK 列在拥有表中不存在。所以在实现包含实时数据的表之间的关系时,需要手动添加FK列。然后,Hibernate 将能够使用像 FKg6wt3d1u6o13gdc1hj36ad1ot 这样的奇怪名称来建立 FK 约束。

所涉及的细微差别通过一个稍微更详细的示例来说明。考虑一个数据库,其中实体联系人将是连接 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)

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

于 2017-07-02T23:01:53.683 回答