为什么@OneToOne允许重复关联?

时间:2012-01-23 07:20:08

标签: jpa one-to-one

我有User和Address类,如下所示:

class User
{
   ...
   ...
   @OneToOne( cascade=CascadeType.ALL)
   @JoinColumn(name="addr_id")
   private Address address;
}

class Address
{
   ...
   ...
   @OneToOne(mappedBy="address")
   private User user;
}

这里我的假设是这个域模型我可以将一个地址与一个用户相关联(user.addr_id应该是唯一的)。

但是使用这个域模型,我可以创建多个用户并将它们关联到同一个地址。

User u1 = new User();
//set data
Address addr1 = new Address();
//set data
u1.setAddress(addr1);
...
session.save(u1); 

- >这是使用addr_id = 1创建一个地址记录,并在用户表中使用addr_id = 1插入一个用户记录。细

再次

User u2 = new User();
//set data
Address addr1 = (Address) session.load(Address.class, 1);
//set data
u2.setAddress(addr1);
...
session.save(u2);

- >这是创建第二个用户记录并使用addr_id = 1与现有地址相关联,这是不希望的。

我可以使用@OneToOne(..)@ JoinColumn(name =“addr_id”,unique = true)来防止这种情况发生。 但是使用@OneToOne而不是@ManyToOne(..,unique = true)会有什么不同。

@OneToOne本身应该强加“unique = true”condition..right?

-Siva

2 个答案:

答案 0 :(得分:6)

@OneToOne正在注释Java以表达两个类之间关系的想法。如果这是一个@OneToMany,那么我们就有了一个集合。因此,阅读注释,我们了解实际情况,JPA运行时也理解这些。

一对一的实际监管是在数据库中执行的 - 我们需要模式具有唯一性约束。 @JoinColumn表示如何在DatabaseSchema中显示该关系。如果我们生成模式,这可能很有用。

然而,在许多情况下,我们使用自下而上的工具从架构生成Java。在这种情况下,没有实际需要Java注释来反映数据库约束,从Java角度来看,我们只看到这种关系。

如果@JoinColumn的语义与@oneToOne不匹配,智能编译器可能会警告我们,但我不确定当前的实现是否会这样做。

答案 1 :(得分:4)

OneToOne是一个描述对象模型的注释。它说了协会的基数是什么。 unique="true"表示“model-to-ddl”工具在此列上应该有一个唯一的cosntraint。您可以使用这样的工具,但您也可以自己创建和维护数据库模式。

无论您选择做什么,每次修改OneToOne关联以检查基数是否得到遵守时,JPA引擎都不会进行查询。它只是假设代码是正确的,数据库中的唯一约束将确保基数得到尊重。

相关问题