多对多关系 Spring Boot MySQL

huangapple go评论74阅读模式
英文:

many-to-many relationship springboot mysql

问题

我有两个模型User用户和Role角色),它们之间是多对多的关系
我需要添加一个用户并为他分配数据库中已有的特定角色

------User------

@Entity
@Table(name = "user")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_Id")
    private int userId;
    @Column(name = "name")
    private String name;
    @Column(name = "lastname")
    private String lastname;
    @Column(name = "email")
    private String email;
    @Column(name = "password")
    private String password;
    @Column(name = "isActive")
    private boolean isActive;
    @Column(name = "lastActive")
    private String lastActive;
    @Column(name = "createdDate")
    private String createdDate;
    @Column(name = "isBlocked")
    private boolean isBlocked;
    
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "institution_id", nullable = false)
    @JsonIgnoreProperties(value = {"user"})
    private Institution institution;
    
    @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH})
    @JoinTable(name = "user_has_role",
            joinColumns = {
                    @JoinColumn(name = "user_id", referencedColumnName = "user_id",
                            nullable = false, updatable = true)},
            inverseJoinColumns = {
                    @JoinColumn(name = "role_id", referencedColumnName = "role_id",
                            nullable = false, updatable = true)})
    @JsonIgnoreProperties(value = {"users"})
    private Set<Role> roles = new HashSet<>();
}

--------Roles--------

@Entity
@Table(name = "role")
public class Role {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_Id")
    private int roleId;
    @Column(name = "name")
    private String name;
    @Column(name = "description")
    private String description;
    @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY)
    @JsonIgnoreProperties(value = {"roles"})
    private Set<User> users = new HashSet<>();
}

// Application Controller

@PostMapping("/addUser")
public String addUser(@RequestBody User user) {
    userrepository.save(user);
    return "user saved with name: " + user.getName();
}

// JSON请求体

{
    "userId" : 7,
    "name": "test",
    "lastname": "testlast",
    "email": "testtest@yahoo.com",
    "password": "test123",
    "lastActive": "04/05/21",
    "createdDate": "02/04/20",
    "institution": {
        "institutionId": 4
    },
    "roles": [
        {
            "roleId": 2
        }
    ],
    "isActive": false,
    "isBlocked": true
}

一切都正常运行用户-角色表会添加一条记录其中userId为7roleId为2但问题是角色表被更新字段name和description的值被清空并替换为null值请问有什么解决方法吗
英文:

i have 2 models User and roles , its a many to many relation ship.
i need to add a user and give him a specific role already present in my data base.
------User------

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Entity
@Table(name = &quot;user&quot;)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name=&quot;user_Id&quot;)
private int userId;
@Column(name=&quot;name&quot;)
private String name;
@Column(name=&quot;lastname&quot;)
private String lastname;
@Column(name=&quot;email&quot;)
private String email;
@Column(name=&quot;password&quot;)
private String password;
@Column(name=&quot;isActive&quot;)
private boolean isActive;
@Column(name=&quot;lastActive&quot;)
private String lastActive;
@Column(name=&quot;createdDate&quot;)
private String createdDate;
@Column(name=&quot;isBlocked&quot;)
private boolean isBlocked;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = &quot;institution_id&quot;, nullable = false)
@JsonIgnoreProperties(value = {&quot;user&quot;})
private Institution institution;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH})
@JoinTable(name = &quot;user_has_role&quot;,
joinColumns = {
@JoinColumn(name = &quot;user_id&quot;, referencedColumnName = &quot;user_id&quot;,
nullable = false, updatable = true)},
inverseJoinColumns = {
@JoinColumn(name = &quot;role_id&quot;, referencedColumnName = &quot;role_id&quot;,
nullable = false, updatable = true)})
@JsonIgnoreProperties(value = {&quot;users&quot;})
private Set&lt;Role&gt; roles = new HashSet&lt;&gt;();
}

--------Roles--------

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Entity
@Table(name = &quot;role&quot;)
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name=&quot;role_Id&quot;)
private int roleId;
@Column(name=&quot;name&quot;)
private String name;
@Column(name=&quot;description&quot;)
private String description;
@ManyToMany(mappedBy = &quot;roles&quot;, fetch = FetchType.LAZY)
@JsonIgnoreProperties(value = {&quot;roles&quot;})
private Set&lt;User&gt; users = new HashSet&lt;&gt;();
}

and the application's controller

@PostMapping(&quot;/addUser&quot;)
public String addUser(@RequestBody User user) {
userrepository.save(user);
return &quot;user saved with name: &quot; + user.getName();
}

and this is the json body i send with the api request.

{
&quot;userId&quot; : 7,
&quot;name&quot;: &quot;test&quot;,
&quot;lastname&quot;: &quot;testlast&quot;,
&quot;email&quot;: &quot;testtest@yahoo.com&quot;,
&quot;password&quot;: &quot;test123&quot;,
&quot;lastActive&quot;: &quot;04/05/21&quot;,
&quot;createdDate&quot;: &quot;02/04/20&quot;,
&quot;institution&quot;: {
&quot;institutionId&quot;: 4
},
&quot;roles&quot;: [
{
&quot;roleId&quot;: 2
}
],  
&quot;active&quot;: false,
&quot;blocked&quot;: true
}

everything worls just fine to my user-has-role table a record is added with the userId = 7 and roleId=2
but the problem is that the table role is getting updated and the fields name and description are getting erased and replaced by null values...
any ideas please

答案1

得分: 1

您已将CascadeType.PERSIST添加到UserRole@ManyToMany关联中。<br>
当将User实体持久化到实体管理器时,它还将持久化Role实体。由于您在请求负载中传递了Role的主键,它将创建/更新Role表格。

您需要从关联中移除CascadeType.PERSIST,它将按预期工作。

英文:

You have added CascadeType.PERSIST to User and Role @ManyToMany join.<br>
When the User entity is persisted to the EntityManager, it will also persist the Role entity. As you are passing the primary key in the request payload for Role it will create/update the Role table.

You need to remove the CascadeType.PERSIST from joining and it will work as expected.

@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH })
@JoinTable(name = &quot;user_has_role&quot;,
joinColumns = {
@JoinColumn(name = &quot;user_id&quot;, referencedColumnName = &quot;user_id&quot;,
nullable = false, updatable = true)},
inverseJoinColumns = {
@JoinColumn(name = &quot;role_id&quot;, referencedColumnName = &quot;role_id&quot;,
nullable = false, updatable = true)})
@JsonIgnoreProperties(value = {&quot;users&quot;})
private Set&lt;Role&gt; roles = new HashSet&lt;&gt;();

huangapple
  • 本文由 发表于 2020年8月20日 20:49:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63505483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定