【问题标题】:@OneToOne bidirectional mapping with @JoinColumn@OneToOne 与 @JoinColumn 的双向映射
【发布时间】:2012-05-21 14:48:45
【问题描述】:

假设我有一个人

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 映射到其他实体。
我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    你的代码应该是:

    @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。你比我更了解 OP 的问题。他想使用 JoinColumn 注释,但表中没有连接列,这让我感到困惑。
    • @JBNizet 谢谢两位,看起来我完全误解了注释的含义,即使我阅读了文档等等。
    • Guadio79:您现在能告诉我,person_id 列存储在哪里吗?或者我是否必须通过设置person_id 列而不是通过设置Job 属性并保持整个人来保持实体?
    • 在数据库上,您必须创建连接列。最好的办法是让 Hibernate 为你做这件事。您可以尝试输入您的休眠配置属性:hibernate.hbm2ddl.auto=update 并查看休眠创建的语句,然后复制该语句以获得用于创建列的 sql 脚本。
    • @Guaido79 您能否提供上述代码工作所需的完整架构(在两种方法中)?
    【解决方案2】:

    本讨论假设在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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      相关资源
      最近更新 更多