SpringBoot 2.0.4 中同一实体的多种表示 [英] Multiple representations of the same entity in SpringBoot 2.0.4

查看:27
本文介绍了SpringBoot 2.0.4 中同一实体的多种表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本的 SpringBoot 2.0.4.RELEASE 应用程序.使用 Spring Initializer、JPA、嵌入式 Tomcat、Thymeleaf 模板引擎,并打包为可执行 JAR 文件.

I have a basic SpringBoot 2.0.4.RELEASE app. using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file.

我有一个带有角色的用户对象:

I have a User object with roles:

@Entity
@Table(name="t_user")
public class User implements Serializable, UserDetails {


 @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
    @JoinTable(
        name="t_user_role",
        joinColumns=@JoinColumn(name="user_id", referencedColumnName="id"),
        inverseJoinColumns=@JoinColumn(name="role_id", referencedColumnName="id"))
    private Set<Role> roles = new HashSet<>();
..
}

当我启动应用程序时.我创建了所有角色:

When I init the app. I create all the roles:

roleService.save(new Role(RolesEnum.USER.getRoleName()));
roleService.save(new Role(RolesEnum.ADMIN.getRoleName()));

然后我创建一个具有 USER 角色的用户:

Then I create a User with the USER role:

User user1 = new User();


         Role role = roleService.findByName(RolesEnum.USER.getRoleName());

         user.getRoles().add(role);
          userService.save(user);

但是当我创建另一个具有相同角色的用户时:

but When I create another user with the same role:

User user2 = new User();


         Role role = roleService.findByName(RolesEnum.USER.getRoleName());

         user2.getRoles().add(role);
          user2Service.save(user);

我收到此错误:

Multiple representations of the same entity [com.tdk.backend.persistence.domain.backend.Role#1] are being merged. Detached: [com.tdk.backend.persistence.domain.backend.Role@5295d3de]; Detached: [com.tdk.backend.persistence.domain.backend.Role@2b3d9d32]

在角色实体中,我没有声明用户字段,因为我不会根据角色获取所有用户

In the Role entity I don't have the field users declared since I will not get all the users based on a role

推荐答案

您面临这个问题,因为您正在将对象添加到已经可用的列表/集合中.同时使用 oneToMany 映射执行保存操作

you are facing this issue because you are adding the object to the list/set which is already available.while performing save operation with oneToMany mapping

现在从级联中删除 CascadeType.MERGE 是一种解决方案,但不是最好的解决方案,因为从级联中删除 MERGE 后,您将永远无法更新映射对象

Now removing CascadeType.MERGE from cascade is one solution but not a best solution because after removing MERGE from Cascade you won't be able to update the mapped object ever

如果您还想对映射对象执行更新操作和保存操作,那么在将映射对象添加到列表/集合之前,只需在列表中检查/搜索对象,如果映射对象在列表中可用,则执行操作在那个特定的对象上.

If you want to perform update operation also along with save for the mapped objects then before adding mapped object to list/collection just check/search within the list for the object and if the mapped object is available within the list then perform operation on that particular object.

保持级联 = CascadeType.ALL

keep cascade = CascadeType.ALL

Role role = roleService.findByName(RolesEnum.USER.getRoleName());
Note- make sure you have overridden hashcode/equals properly
boolean b = user2.getRoles().contains(role);
if (b!=true){
user2.getRoles().add(role);
}
 user2Service.save(user);

或使用流

Role r= user2.getRoles().stream().filter(oldRole->oldRole.equals(role)).findAny().orElse(null);
        
        if(r==null) {
 user2.getRoles().add(role);
    }
     user2Service.save(user);

这篇关于SpringBoot 2.0.4 中同一实体的多种表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆