我有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
答案 0 :(得分:6)
一对一的实际监管是在数据库中执行的 - 我们需要模式具有唯一性约束。 @JoinColumn表示如何在DatabaseSchema中显示该关系。如果我们生成模式,这可能很有用。
然而,在许多情况下,我们使用自下而上的工具从架构生成Java。在这种情况下,没有实际需要Java注释来反映数据库约束,从Java角度来看,我们只看到这种关系。
如果@JoinColumn的语义与@oneToOne不匹配,智能编译器可能会警告我们,但我不确定当前的实现是否会这样做。
答案 1 :(得分:4)
OneToOne是一个描述对象模型的注释。它说了协会的基数是什么。 unique="true"
表示“model-to-ddl”工具在此列上应该有一个唯一的cosntraint。您可以使用这样的工具,但您也可以自己创建和维护数据库模式。
无论您选择做什么,每次修改OneToOne关联以检查基数是否得到遵守时,JPA引擎都不会进行查询。它只是假设代码是正确的,数据库中的唯一约束将确保基数得到尊重。