SpringBoot 2.0.4中同一实体的多种表示形式

时间:2018-08-25 20:33:56

标签: hibernate spring-mvc spring-boot spring-data-jpa spring-data

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

我有一个具有以下角色的User对象:

function listEvents(auth) {

    const calendar = google.calendar({version: 'v3', auth});

    calendar.events.list({
...

当我初始化应用程序时。我创建了所有角色:

@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<>();
..
}

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

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

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

User user1 = new User();


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

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

我收到此错误:

User user2 = new User();


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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

保持级联 = 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);

答案 1 :(得分:0)

根据我的说法,您已在Role实体上使用 cascade = CascadeType.MERGE 。 请删除,它将解决问题。