SpringBoot + JPA @ManyToMany的操作要点说明

目录
  • SpringBoot + JPA @ManyToMany 要点
    • 对应的Entity的建立
    • Junit的测试
  • JPA中ManyToMany关系问题
    • 解决办法

SpringBoot + JPA @ManyToMany 要点

这里主要时记录下此种方法的注意事项。

环境 :mysql 引擎为innoDB ,否则没有事务的说法的。

#不加这句则默认为myisam引擎
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

对应的Entity的建立

此处注意不可使用lombok @Data 注解。使用@Setter 、@Getter注解。主要原因时要自己覆写hash() equals(),toString() 方法。这样添加和删除的时候不会出现异常。否则出现循环的引用,不能删除或stackOver;

User

@Setter
@Getter
@Entity
public class User {
    @Id
    @GenericGenerator(name="jpauuid",strategy = "org.hibernate.id.UUIDGenerator")
    @GeneratedValue(generator = "jpauuid")
    @Column(length = 32,nullable = false)
    private String  id;
    @Column(length = 30)
    private String username;
    @ManyToMany(cascade = CascadeType.REFRESH,mappedBy = "users")
    private Set<Role> roles;
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return id.equals(user.id) &&
                username.equals(user.username) &&
                roles.equals(user.roles);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, username, roles);
    }
    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", username='" + username + '\'' +
                ", roles=" + roles +
                '}';
    }
}

Role

@Setter
@Getter
@Entity
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    @Column(length = 30)
    private String  name;
    @ManyToMany(cascade = CascadeType.REFRESH)
    @JoinTable(name = "user_role",joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name="user_id"))
    private Set<User>  users;
    public void addUser(User user){
        this.users.add(user);
    }
    public void removeUser(User user){
        this.users.remove(user);
    }
}

Junit的测试

注意@transaction的注解一定要加上。并且@Rollback(value = false) 也加上。springboot-test 默认在内存中save,不提交,所有以通过了但是数据库中无内容,官方说为了不影响上下文环境。

   /**
     * 添加角色
     */
    @Test
    public void addRole(){
        Role role = new Role();
        role.setName("系统管理员");
        roleRepository.save(role);
    }
    /**
     * 添加用户
     */
    @Test
    public void addUser() {
        User user = new User();
        user.setUsername("test1");
        userRepostitory.save(user);
    }
    /**
     *
     * 通过关系维护方添加角色和用户的关系
     */
    @Test
    @Transactional
    @Rollback(value = false)
    public void  addUserRole(){
        User user = userRepostitory.findByUsername("test1");
        Role role = roleRepository.getOne(1);
        role.addUser(user);
        roleRepository.saveAndFlush(role);
    }
    /**
     *
     * 删除对应的关联数据
     */
    @Test
    @Transactional
    public void removeRoleUser(){
        User user = userRepostitory.findByUsername("test1");
        Role role = roleRepository.getOne(1);
        role.removeUser(user);
        roleRepository.saveAndFlush(role);
    }

不能删除和添加成功,出现循环的主要问题在 toString()方法。此方法只能包含基本的元素,不要包含相应的@ManyToMany 的对象。两个类都是。这样才会ok.

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoBeetlApplicationTests {
    @Autowired
    private UserRepostitory userRepostitory;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private UserGroupRepository userGroupRepository;
    @Autowired
    private PriviledgeRepository priviledgeRepository;
    @Autowired
    private MenuRepository menuRepository;
    @Autowired
    private FileRepository fileRepository;
    @Autowired
    private ElementRepository elementRepository;
    @Autowired
    private OperationRepository operationRepository;
    @Test
    public void contextLoads() {
        System.out.println("helle junit");
    }
    /**
     * 添加角色
     */
    @Test
    public void addRole(){
        Role role = new Role();
        role.setName("系统管理员");
        roleRepository.save(role);
    }
    /**
     * 添加用户
     */
    @Test
    public void addUser() {
        User user = new User();
        user.setUsername("test1");
        userRepostitory.save(user);
    }
    /**
     *
     * 通过关系维护方添加角色和用户的关系
     *
     *
     */
    @Test
    @Transactional
    @Rollback(value = false)
    public void  addRoleUser(){
        User user = userRepostitory.findByUsername("test1");
        Role role = roleRepository.getOne(2);
        role.addUser(user);
        roleRepository.saveAndFlush(role);
    }
    /**
     *
     * 删除对应的关联数据
     */
    @Test
    @Transactional
    @Rollback(value = false)
    public void removeRoleUser(){
        Role role = roleRepository.getOne(2);
        User user = userRepostitory.findByUsername("test1");
        role.removeUser(user);
        roleRepository.saveAndFlush(role);
    }
    /**
     *
     * 删除单一的角色是可以删除相应的关系
     */
    @Test
    public void removeRole(){
        Role role = roleRepository.getOne(2);
        roleRepository.delete(role);
    }
    /**
     *
     * 删除用户不能联动删除关系,
     * 这个时不能执行的,只能在数据维护端来进行删除后,在进行相应的用户删除。
     *
     */
    @Test
    public  void removeUser(){
        Role role = roleRepository.getOne(2);
        User user = userRepostitory.findByUsername("test1");
        role.removeUser(user);
        userRepostitory.delete(user);
    }

JPA中ManyToMany关系问题

配置JPA的时候多对多关系,报以下错误:

org.hibernate.AnnotationException: Illegal use of mappedBy on both sides of the relationship: com.csair.gme.core.domain.ComponentType.componentPropertys

解决办法

不能两边都用mappedBy,只能用一边,而且用mappedBy的那一边是从表,另外一边就是主表。mappedBy=‘主表里的变量名'

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • springboot 之jpa高级查询操作

    springboot的jpa可以根据方法名自动解析sql 非常方便, 只需要在 dao接口中定义方法即可; 下面是一个 demo package com.bus365.root.dao; import java.io.Serializable; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.reposi

  • springboot整合JPA过程解析

    这篇文章主要介绍了springboot整合JPA过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 接下来具体看看是怎么弄的. 1.新建一个springboot项目,选择web.data jdbc.data jpa.mysql driver. 2.建立以下目录及结构: pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&

  • spring jpa ManyToMany原理及用法详解

    1.java和jpa 中所有的关系都是单向的.这个关系数据库不同,关系数据库,通过外键定义并查询,使得反向查询总是存在的. 2.JPA还定义了一个OneToMany关系,它与ManyToMany关系类似,但反向关系(如果已定义)是ManyToOne关系. OneToMany与JPA中ManyToMany关系的主要区别在于,ManyToMany总是使用中间关系连接表来存储关系, OneToMany可以使用连接表或者目标对象的表引用中的外键源对象表的主键. @OneToMany(cascade =

  • SpringBoot + JPA @ManyToMany的操作要点说明

    目录 SpringBoot + JPA @ManyToMany 要点 对应的Entity的建立 Junit的测试 JPA中ManyToMany关系问题 解决办法 SpringBoot + JPA @ManyToMany 要点 这里主要时记录下此种方法的注意事项. 环境 :mysql 引擎为innoDB ,否则没有事务的说法的. #不加这句则默认为myisam引擎 spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDial

  • Springboot JPA 枚举Enum类型存入到数据库的操作

    1.使用JPA 的@Enumerated 注解 ,可以直接将Enum映射到数据库中. 但是value的值只有两种方式选择,一种是使用枚举的序号映射,一种是枚举的名称来映射. public enum EnumType { /** Persist enumerated type property or field as an integer. */ ORDINAL, /** Persist enumerated type property or field as a string. */ STRIN

  • IDEA+maven+SpringBoot+JPA+Thymeleaf实现Crud及分页

    一.开发环境: 1.windows 7 企业版 2.IDEA 14 3.JDK 1.8 4.Maven 3.5.2 5.MariaDB 6.SQLYog 二.Maven设置: Maven目录下的conf目录下的settings.xml做如下内容的添加: 1.使用阿里云的仓库,比官网访问速度快很多 <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexu

  • springboot jpa分库分表项目实现过程详解

    这篇文章主要介绍了springboot jpa分库分表项目实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 分库分表场景 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库.优化索引,做很多操作时性能仍下降严重.此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间. 分库分表用于应对当前互联网常见的两个场景--大数

  • SpringBoot JPA懒加载失效的解决方案(亲测有效)

    SpringBoot JPA懒加载失效 使用springBoot JPA 对两个实体类进行双向关联,并设置了懒加载,如下: 然后在查询后用到了roles,会报错, 解决办法如下: 1. 在配置文件中加入: spring.jpa.properties.hibernate.enable_lazy_load_no_trans =true 2. 如果你是在SpringBoot的测试类 中使用报错,则在方法上加入@Transactional注解 在百度查询时发现有人说 修改该配置: spring.jpa.

  • springboot + JPA 配置双数据源实战

    目录 springboot + JPA 配置双数据源 1.首先配置application.yml文件设置主从数据库 2.使用配置类读取application.yml配置的两个数据源 3.然后通过类的方式配置两个数据源 4.启动类主函数入口 springboot + JPA 配置双数据源 1.首先配置application.yml文件设置主从数据库 spring: servlet: multipart: max-file-size: 20MB max-request-size: 20MB prof

  • JPA @ManyToMany 报错StackOverflowError的解决

    目录 JPA @ManyToMany 报错StackOverflowError SpringJPA批量删除引起的StackOverFlow 解决方法 JPA @ManyToMany 报错StackOverflowError 在使用 SpringBoot + JPA 的@ManyToMany 遇到了如下报错 java.lang.StackOverflowError: null 2021-02-07 10:59:59.490 ERROR 100440 --- [io-20012-exec-3] o.

  • springboot jpa之返回表中部分字段的处理详解

    目录 springboot jpa返回表中部分字段 JPA 自定义返回字段 springboot jpa返回表中部分字段 使用springboot jpa操作数据库可以加快我们的开发效率,对于简单的crud操作来说,使用jpa来开发不要太爽,但是说实话对于一些复杂的数据库操做jpa使用起来就不是这么爽了. 在开发中很多时候我们要返回的可能只是数据库表中或某个类中的一部分字段,这个要是用mybatis的话就很简单,直接在sql中select字段就好了,规范一点就数据传输类接一下,偷个懒的话直接用m

  • SpringBoot+JPA 分页查询指定列并返回指定实体方式

    目录 SpringBoot+JPA分页查询指定列并返回指定实体 SpringBoot JPA实现自定义语句分页查询 SpringBoot+JPA分页查询指定列并返回指定实体 用习惯Mybatis,没用过jpa 真是各种踩坑了 脑壳疼,一个分页弄老半天,原来就一句话的事情,唉 先来说说正常的JPA如何操作 实体类对应表来创建,举个例子 @Entity @Table(name = "td_user") public class TdUser extends BaseModel { priv

  • SpringBoot+Jpa项目配置双数据源的实现

    目录 引言 配置yml文件 创建数据源配置类 为每个数据库创建配置类 引言 今天为大家带来一些非常有用的实战技巧,比如在我们需要对两个数据库进行操作的时候而哦我们通常用的只是单数据库查询,这就触及到知识盲点了,那么废话不多说上代码! 配置yml文件 server: port: 8080 spring: profiles: active: dev jackson: time-zone: GMT+8 # 这里是我们的数据库配置地方 datasource: data1: #这里是数据库一 driver

随机推荐