当前位置:   article > 正文

springboot jpa外键 (user role)双向多对多@ManyToMany(原创)_user role 中间表 jpa

user role 中间表 jpa

多个用户可能有多个角色,多个角色可能有多个用户。所以这种情况下就使用双向@ManyToMany进行关联(单项也可以,根据业务需求)

jpa会自动生成中间表,java的entity代码中只需要User类和Role类,无需创建中间表user_role类(sql建表语句中可以手动创建该中间表,不手动创建jpa系统也会帮忙自动创建)

注意:

不能用lombok的@EqualsAndHashCode和@ToString,否则死循环内存溢出

一、表结构

User表:

  1. package com.cmit.oag.backend.entity.common;
  2. @Entity
  3. @Getter
  4. @Setter
  5. //@EqualsAndHashCode//不能用@EqualsAndHashCode和@ToString,否则死循环内存溢出
  6. @Table(name = "user")
  7. public class User implements Serializable {
  8. private static final long serialVersionUID = 1L;
  9. @Id
  10. @GeneratedValue(strategy = GenerationType.IDENTITY)
  11. private Long id;
  12. @NotBlank(message = "昵称不能为空")
  13. @Column(name = "user_name")
  14. private String userName;
  15. @NotBlank(message = "密码不能为空")
  16. @Column(name = "password")
  17. private String password;
  18. @Column(name = "status")
  19. private Integer status;
  20. // @JsonIgnoreProperties("users")
  21. @JsonIgnore
  22. @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE})//建议MERGE
  23. @JoinTable(name = "user_role", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
  24. private Set<Role> roles;
  25. }

Role表:

  1. package com.cmit.oag.backend.entity.common;
  2. @Entity
  3. @Getter
  4. @Setter
  5. //@EqualsAndHashCode//不能用@EqualsAndHashCode和@ToString,否则死循环内存溢出
  6. @Table(name = "role")
  7. public class Role {
  8. @Id
  9. @GeneratedValue(strategy = GenerationType.IDENTITY)
  10. private Long id;
  11. @Column(name = "name")
  12. private String name;
  13. @Column(name = "status")
  14. private Integer status;
  15. @Column(name = "description")
  16. private String description;
  17. // @JsonIgnoreProperties(value = { "roles" })
  18. @JsonIgnore
  19. @ManyToMany(mappedBy = "roles",fetch = FetchType.EAGER, cascade = {CascadeType.MERGE}) //建议MERGE//mappedBy对方配置关系的属性名称,表示由对方来维护中间表关系
  20. private Set<User> users = new HashSet<>();
  21. }

sql:

  1. create table user_role
  2. (
  3. id bigint(20) primary key AUTO_INCREMENT,
  4. user_id bigint(20) NOT NULL,
  5. role_id bigint(20) NOT NULL
  6. # 这里外键可以不用设置,jpa代码中加以@ManyToMany控制就行了
  7. # CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  8. # CONSTRAINT `fk_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
  9. ) ENGINE = InnoDB DEFAULT CHARSET = utf8;

二、cascade = {CascadeType.MERGE}

重要的事情说三遍:

建议使用cascade = {CascadeType.MERGE}
建议使用cascade = {CascadeType.MERGE}
建议使用cascade = {CascadeType.MERGE}

而不是{CascadeType.ALL}!!

务必参看https://blog.csdn.net/HD243608836/article/details/116137170

三、有个疑问:

双向@ManyToMany时,查询user的时候,role中包含着user,user中又包含着role...如此无限循环为什么jvm内存没有溢出???还请路过的大神评论区帮忙讲解一下。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/1009367
推荐阅读
相关标签
  

闽ICP备14008679号