[英]Spring data jpa detached entity
我開始使用Spring Data JPA在Spring Boot應用程序上設置用戶和角色之間的ManyToMany關系。
此關系在User類中定義如下:
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name="user_role", joinColumns = {@JoinColumn(name="user_id")}, inverseJoinColumns = {@JoinColumn(name="role_id")})
private Set<UserRole> roles;
我用以下方法創建角色
@Transactional
private void generateSeedRoles() {
UserRole adminRole = new UserRole(RoleEnum.ADMIN.toString());
userRoleRepository.save(adminRole);
UserRole userRole = new UserRole(RoleEnum.USER.toString());
userRoleRepository.save(userRole);
}
之后為用戶分配角色失敗:
@Transactional
private void generateSeedUsers() {
UserRole adminRole = userRoleRepository.findUserRoleByRoleName("ADMIN");
User user = User.createUser("user1", "user1@user.com", "pass");
user.setRoles(new HashSet<UserRole>(Arrays.asList(adminRole)));
userRepository.save(user);
}
拋出以下異常(為便於閱讀而格式化):
org.springframework.dao.InvalidDataAccessApiUsageException:
detached entity passed to persist: co.feeb.models.UserRole;
nested exception is org.hibernate.PersistentObjectException:
detached entity passed to persist: co.feeb.models.UserRole
但是,如果在創建關系之前保存用戶,則它可以正常工作:
@Transactional
private void generateSeedUsers() {
UserRole adminRole = userRoleRepository.findUserRoleByRoleName("ADMIN");
User user = User.createUser("user1", "user1@user.com", "pass");
//Save user
userRepository.save(user);
//Build relationship and update user
user.setRoles(new HashSet<UserRole>(Arrays.asList(adminRole)));
userRepository.save(user);
}
必須保存/更新用戶兩次對我來說似乎有些不合理。 有沒有辦法將收到的角色分配給新用戶而不先保存用戶?
當您保存實體時,Spring會在內部檢查實體是否是新的(我忘記確切的機制),並發出持久性(如果是新的)或合並(如果存在)。
由於您已經使用Cascade.ALL定義了User與UserRole的關系,因此來自User的任何持久/合並也將級聯到UserRole。
鑒於Spring如何實現保存以及上面級聯的行為,以下是一些需要考慮的方案:
如果您可以保證添加到用戶關系的任何UserRole始終存在,您只需從級聯選項中刪除Cascade.Persist即可。 否則,我相信在上述兩種情況下保存用戶時,您必須使用合並 - 通過自定義存儲庫和entityManager。
關於你使用Cascade.ALL,在這種情況下可能沒有意義,因為你有一個@ManyToMany關系,從用戶到UserRole級聯ALL可能會產生一些不良影響(例如Cascade.Remove會每次刪除UserRole用戶被刪除)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.