2014-08-31 194 views
1

我创建了这样一个单向的一比一的关系:Hibernate的一对一允许多对一

@Entity(name="person") 
public class Person { 

    @Id 
    @GeneratedValue 
    @Column(name = "pid", unique = true) // note 2 
    private int id; 

    // more fields 

    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name="address_id", unique = true) // note 1 
    private Address address; 

    // rest of class 
} 

@Entity(name="address") 
public class Address { 

    @Id 
    @GeneratedValue 
    @Column(name = "aid", unique = true) 
    private int id; 

    // rest of class 
} 

注1:

如果我不指定“ADDRESS_ID”列是唯一这样

@JoinColumn(name="address_id") 

那么它是不是唯一的,我可以有很多的人指的是同一个地址是这样一个多到一的关系:

Person person1 = new Person(); 
Person person2 = new Person(); 
Address address = new Address("21th street"); 
person1.setAddress(address); 
person2.setAddress(address); 

不应该有一对一的关系使外键“address_id”在默认情况下是唯一的吗?

注2:

虽然我指定它的ID不是唯一的。为什么?

+0

您是否尝试过在其中具有personId的地址,该地址需要是具有@ OneToOne/@ JoinColumn的Person类型? – ND27 2014-08-31 20:03:10

+0

这不会使它成为单向的。 – Styl 2014-08-31 21:56:48

回答

0

按照JPA规范2.10.3.1应该是默认创建的唯一约束

表A中包含的外键表B中的外键列名 形成为的串联以下内容: 关系属性或实体A的字段的名称; “_”;表B中的 主键列的名称。外键列与表B的主键具有相同的 类型,并且对其具有唯一键 约束。

因此,Hibernate似乎违反了该规范的这一部分。我似乎记得EclipseLink也做了(或做到了)。你应该能够在Stackoverflow中找到关于它的另一个问题。 DataNucleus最后做了我看。

2

Hibernate不强制唯一性。这是数据库的工作。

对于您的OneToOne,请确保address_id列上存在唯一约束。对于这些ID,确保ID列上有一个主键约束(强制唯一性)。

如果使用Hibernate DDL生成数据库,Hibernate会使用注释的属性:@Id会创建一个PK,而unique = true会生成一个唯一的约束。

但是对于任何认真的工作,我会自己生成架构,使用像FlywayDB或Liquibase这样的工具,它允许将架构从版本迁移到版本。

+0

我的问题是为什么不休眠强制执行唯一性。一对一注释只是定义关系的标记吗?在ID上唯一= true也不会使其唯一。 – Styl 2014-08-31 18:43:49

+0

是否有为该ID创建的PK限制?如果有一个,那么它是唯一的,因为PK是隐式唯一的(否则,它们不会是PK)。比利弗罗斯特的答案似乎表明,默认情况下,Hibernate应该为OneToOne生成一个唯一的约束。它似乎没有。所以,添加unique = true,它会自己定义模式。 – 2014-08-31 18:47:21

+0

谢谢你的时间。那么,Hibernate DDL生成器是不完整的还是这是故意的? – Styl 2014-08-31 21:49:09