Java 休眠一对一允许多对一

Java 休眠一对一允许多对一,java,hibernate,jpa,Java,Hibernate,Jpa,我创建了一个单向的一对一关系,如下所示: @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="

我创建了一个单向的一对一关系,如下所示:

@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
}
Person person1 = new Person();
Person person2 = new Person();
Address address  = new Address("21th street");
person1.setAddress(address);
person2.setAddress(address);
注1:

如果我没有像这样指定“address\u id”列是唯一的

   @JoinColumn(name="address_id")
那么它不是唯一的,我可以让很多人引用相同的地址,这是一种多对一的关系,如下所示:

@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
}
Person person1 = new Person();
Person person2 = new Person();
Address address  = new Address("21th street");
person1.setAddress(address);
person2.setAddress(address);
默认情况下,一对一关系不应该使外键“address_id”唯一吗

注2:


虽然我指定了id,但它不是唯一的。为什么?

根据JPA规范2.10.3.1,默认情况下应创建唯一的约束

表A包含表B的外键。外键列名 由以下内容串联而成: 实体A的关系属性或字段;"_"; 名称 表B中的主键列。外键列具有相同的 键入表B的主键,并且有一个唯一的键 对它的限制


所以Hibernate似乎违反了规范的这一部分。我似乎记得EclipseLink也这样做(或确实这样做)。你应该可以在Stackoverflow中找到关于它的另一个问题。DataNucleus在我上次查看时做得很好。

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

对于OneTONE,请确保
address\u id
列上有唯一的约束。对于ID,请确保ID列上存在主键约束(强制唯一性)

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


但对于任何严肃的工作,我都会使用FlywayDB或Liquibase之类的工具自己生成模式,这样可以将模式从一个版本迁移到另一个版本。

我的问题是为什么hibernate不强制唯一性。一对一注释只是定义关系的标记吗?id上的ALWAL unique=true不会使其唯一。是否为id创建了PK约束?如果有,那么它是唯一的,因为PKs是隐式唯一的(否则,它们就不是PKs)。比利·弗罗斯特的回答似乎表明,默认情况下,Hibernate应该为OneTONE生成唯一的约束。似乎没有。因此,添加unique=true,它将自动创建或定义模式。感谢您抽出时间。那么,Hibernate DDL生成器是不完整的还是故意的?我不知道。问问他们。你有没有试过在地址中有一个personId,它必须是Person类型,上面有@OneToOne/@JoinColumn?这不会使它成为单向的。