java – Spring数据jpa分离实体
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Spring数据jpa分离实体,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2550字,纯文字阅读大概需要4分钟。
内容图文
我开始使用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如何实现保存以及上面级联的行为,以下是一些需要考虑的方案:
>如果User和UserRole都是新的 – 你在保存用户时会得到一个持久的动作,并且一个级联的持久存在UserRole,因为UserRole是新的,所以工作正常.
>如果User是新的但UserRole已经存在 – 再次保存User时会得到一个持久动作,并且级联持续存在UserRole,这会导致错误,因为UserRole已经存在!
如果您可以保证添加到用户关系的任何UserRole始终存在,您只需从级联选项中删除Cascade.Persist即可.否则,我相信在上述两种情况下保存用户时,您必须使用合并 – 通过自定义存储库和entityManager.
关于你使用Cascade.ALL,在这种情况下可能没有意义,因为你有一个@ManyToMany关系,从用户到UserRole级联ALL可能会产生一些不良影响(例如Cascade.Remove会每次删除UserRole用户被删除).
内容总结
以上是互联网集市为您收集整理的java – Spring数据jpa分离实体全部内容,希望文章能够帮你解决java – Spring数据jpa分离实体所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。