Java JPA:OneTONE关系所有者
我想通过Java JPA:OneTONE关系所有者,java,hibernate,jpa,orm,Java,Hibernate,Jpa,Orm,我想通过User.id和Address.User\u id列建立两个模型之间的关系 我创建了两个具有一对一关系的表: @Entity() @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @OneToOne(cascade = CascadeType.ALL) @Join
User.id
和Address.User\u id
列建立两个模型之间的关系
我创建了两个具有一对一关系的表:
@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\u id
我所期望的
我创建地址
实例并将其添加到用户
:
User user = entityManager.find(User.class, 69);
Address address = new Address();
address.setCity("Тест");
userTransaction.begin();
user.setAddress(address);
entityManager.merge(user);
userTransaction.commit();
在我调用合并(用户)
之后。数据成功保存。。。没有任何关系信息
UPD:
使用下面的配置,JPA将创建关系列Address.user\u id
(仅交换了关系所有者)
但在保存地址后,用户id
为空。。。(其他列正在填写)
UPD2:
谢谢。第二个配置工作正常,当设置反向侧关系字段时(如注释中所示):
但我不明白,为什么first config(用户是拥有方)不起作用。因为它是双向的一对一
,所以在持久化父/超级实体之前,还需要将反向设置为所谓的父实体
Address addr = new Address()
user.setAddress(addr);
addr.setUser(user);
session.save(user);
因为它是双向的一对一
,所以在持久化父/超级实体之前,您还需要将反向侧设置为所谓的父实体
Address addr = new Address()
user.setAddress(addr);
addr.setUser(user);
session.save(user);
我将继续使用原始配置,其中用户是拥有方。关于你的模式,这对我来说更有意义 关于地址上的
user\u id
列。。您必须确保在关系的两侧都设置了依赖项。因此,您的跨国家方法应包含以下内容:
if (user.getAddress() == null) {
Address address = createAddress();
address.setUser(user);
user.setAddress(address);
}
我将继续使用原始配置,其中用户是拥有方。关于你的模式,这对我来说更有意义 关于地址上的
user\u id
列。。您必须确保在关系的两侧都设置了依赖项。因此,您的跨国家方法应包含以下内容:
if (user.getAddress() == null) {
Address address = createAddress();
address.setUser(user);
user.setAddress(address);
}
这是因为您对初始配置的期望存在逻辑错误 您声明
User
为关系的拥有方。Owning表示表示表示关系的外键将保留在USER
表中,而不是Address
表中
同时,您用@JoinColumn(name=“id”,referencedColumnName=“User\u id”)
注释了User.address
。基本上,我认为您试图强制address
表保存外键。但是在这种情况下,地址应该是拥有方
如果您想让初始配置正常工作,您只需将当前的JoinColumn
注释替换为@JoinColumn(name=“address\u id”)
。外键将在USER
表中结束。在持久化实体时,必须设置User.address
;设置地址。用户是可选的
如果您确实需要在地址
表中输入密钥,请将地址
表设为拥有方(然后,您只需确保在持久化时间设置地址.user
;但是,您仍然希望设置用户.Address
,以便级联工作,除非明确持久化地址
实体).这是因为您对初始配置的期望存在逻辑错误
您将User
声明为关系的拥有方。拥有意味着表示关系的外键将保留在User
表中,而不是Address
表中
同时,您用@JoinColumn(name=“id”,referencedColumnName=“User\u id”)
注释了User.address
。基本上,我认为您试图强制address
表保存外键。但是在这种情况下,address
应该是拥有方
如果您想让初始配置正常工作,您只需将当前的JoinColumn
注释替换为@JoinColumn(name=“address\u id”)
。外键将在USER
表中结束。在持久化实体时,必须设置USER.address
;设置address.USER
是可选的
如果您确实需要在地址
表中输入密钥,请将地址
表设为拥有方(然后,您只需确保在持久化时间设置地址.user
;但是,您仍然希望设置用户.Address
,以便级联工作,除非明确持久化地址
实体)