更新孩子时如何更新jpa中双向关系所有者的fk
Posted
技术标签:
【中文标题】更新孩子时如何更新jpa中双向关系所有者的fk【英文标题】:How to update the fk of owner of bidirectional relation in jpa when child is updated 【发布时间】:2020-01-10 10:33:06 【问题描述】:第一个定义
简单地说,我有 2 个实体,第一个是用户,第二个是地址,每个用户可以有一个或多个地址。这意味着,我想要用户和地址之间的双向 OneToMany 关系。
问题
当我更新我的用户并删除一些地址(具有 2 个地址列表的用户)时,我有一个具有 3 个地址的用户(具有 3 个地址列表的用户),然后保存用户,地址的 fk 是没有更新。
我希望我的新用户在更新后有 2 个地址,但地址没有改变。
简而言之:当我从用户更新地址表的列表时,地址表的 fk 没有更新。
用户实体(只写地址字段)
@Entity
@Table(name = TABLE_NAME)
public class User
public static final String TABLE_NAME = "User";
//Some Fields Like ID , name ,...
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
@JsonManagedReference
private List<Address> addresses;
public List<Address> getAddresses()
return addresses;
public void setAddresses(List<Address> addresses)
this.addresses = addresses;
地址实体(只写用户字段)
@Entity
@Table(name = TABLE_NAME)
public class Address
public static final String TABLE_NAME = "ADDRESS";
//Some Fields Like ID , name ,...
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
@JsonBackReference
private User user;
public User getUser()
return user;
public void setUser(User user)
this.user = user;
服务类
@Service
public class UserService
@Autowired
UserRepository repository;
public updateUserAddress()
//Get User With Id of 1
User user = repository.findById(1L);
//Get Addresses
List<Address> addresses = user.getAddresses();
//Delete One Address From List
addresses.remove(0);
//Set New Address to User Entity
user.setAddresses(addresses);
//Save User
repository.save(user)
//It doesn't work (List of Address of user is the same and not changed)
顺便说一句,我使用 Spring-data-jpa 和 Hibernate 作为 DAO 层。
【问题讨论】:
更改用户中地址的cascadeType或通过地址列表删除地址。 你试过orphanRemoval = true
吗?
孤儿删除删除子,我不想删除行,我要更新地址表的fk。
您的默认FlushModeType
是什么?您是否尝试过明确EntityManager.flush()
?
我使用的是 spring 数据而不是实体管理器!
【参考方案1】:
通过在User
实体中添加removeAddress
方法,可以更新address
表的fk,也可以保留行:
public void removeAddress(Address address)
address.setUser(null); // or the value you want
updateUserAddress
方法应该是这样的:
public void updateUserAddress()
User user = repository.findById(1L);
List<Address> addresses = user.getAddresses();
Address address = addresses.get(0); //the address to be removed
user.removeAddress(address);
user.setAddresses(addresses);
repository.save(user);
用户实体:
@Entity
@Table(name = "users")
public class User
// other fields
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch=FetchType.EAGER)
@JsonManagedReference
private List<Address> addresses;
// getters, setters, constructors etc.
// the remove method
public void removeAddress(Address address)
address.setUser(null);
地址实体:
@Entity
@Table(name = "address")
public class Address
// other fields
@ManyToOne
@JoinColumn(name = "user_id")
@JsonBackReference
private User user;
// getters, setters, constructors etc.
【讨论】:
以上是关于更新孩子时如何更新jpa中双向关系所有者的fk的主要内容,如果未能解决你的问题,请参考以下文章