2017-05-14 51 views
1

我想User.idAddress.user_idJPA:OneToOne关系所有者

使2款之间的关系

创建两个表一比一的关系:

@Entity() 
@Table(name = "user") 
public class User { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "id", referencedColumnName = "user_id") 
    private Address address; 

    public int getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    public Address getAddress() { 
     return address; 
    } 

    public void setAddress(Address address) { 
     this.address = address; 
    } 

} 



@Entity 
@Table(name = "address") 
public class Address extends com.mezoline.domain.common.Entity { 

    @Id 
    @GeneratedValue 
    private int id; 

    @OneToOne(mappedBy = "address") 
    private User user; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

} 

在这里,我已经可以看到问题:hibernate没有生成数据库列Address.user_id我的预期如何。

创建Address实例,并添加到User

User user = entityManager.find(User.class, 69); 
    Address address = new Address(); 
    address.setCity("Тест"); 
    userTransaction.begin(); 
    user.setAddress(address); 
    entityManager.merge(user); 
    userTransaction.commit(); 

我打电话merge(user)后。数据成功保存...没有任何关系信息。

UPD:

下面的配置,JPA将创建关系列Address.user_id(只是老板的关系被交换)

public class User { 
    ... 
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "user") 
    private Address address; 
    ... 
} 

public class Address { 
    .... 
    @OneToOne() 
    @JoinColumn(name = "user_id") 
    private User user; 
    .... 
} 

但后保存Address.user_id为空...(其它列正在填充)

UPD2:

谢谢。其次配置做工精细,当设置反方关系领域(如评论建议):

Address address = createAddress(); 
address.setUser(user); 
user.setAddress(address); 

但我不`吨明白,为什么第一个配置(用户是拥有方)唐不工作。

回答

2

这是因为您对初始配置的期望有逻辑错误。

您声明User拥有一方的关系。 拥有表示表示该关系的外键将保留在USER表中,而不保留在Address表中。

与此同时,您注释了User.address@JoinColumn(name = "id", referencedColumnName = "user_id")。基本上,我认为你试图强制ADRESS表保存外键。但在这种情况下,Adress应该是拥有方

如果你想要初始配置工作,你应该做的就是你应该用@JoinColumn(name = "address_id")替换当前的JoinColumn注释。外键将在USER表中结束。当坚持实体时,必须设置User.address;设置Address.user是可选的。

如果你绝对必须的ADDRESS表中的键,使Address台拥有方(那么你只需要确保Address.user设定在持续时间;但是,你还是会希望User.address被设置以便级联工作,除非明确坚持Address实体)。

1

因为它是双向One-to-One,还需要持续的父/超级实体之前设置反侧所谓的母公司。

Address addr = new Address() 
user.setAddress(addr); 
addr.setUser(user); 
session.save(user); 
+0

嗯..谢谢。我认为JPA管理自己..(AOP) – Hett

1

我会留在原配置,用户是拥有的一方。对于我来说,对你的模式更有意义。

关于Address上的user_id列..您必须确保在关系的两侧都设置了依赖关系。所以你的transanctional方法应该包含以下内容:

if (user.getAddress() == null) { 
    Address address = createAddress(); 
    address.setUser(user); 
    user.setAddress(address);   
} 
+0

第一次配置休眠不创建列Address.user_id .. – Hett