【问题标题】:Clear ManyToMany Relationship with JPA / JPQL清除与 JPA / JPQL 的多对多关系
【发布时间】:2020-11-26 01:55:39
【问题描述】:

我有用户和角色。每个用户可以有多个角色。

我想要进行批量操作,例如删除所有用户角色但保留用户和角色。 那么我怎样才能只截断 manyToMany 表呢?

很长的路要走 findAllUsers -> 对于每个 user.roles = new Hashset() -> saveAll(users)

@Entity
@Table
public class Role {

    @Id
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<>();
}
@Entity
@Table
public class User {

    @Id
    @Column(name = "id", unique = true, nullable = false)
    private Long id;

    @ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST})
    @JoinTable(
            name = "UserRole",
            joinColumns = {@JoinColumn(name = "id")},
            inverseJoinColumns = {@JoinColumn(name = "id")})
    private Set<Role> roles = new HashSet<>();
}
@Repository
public interface UsersRepository extends JpaRepository<User, Long> {

    @Modifying
    @Query("UPDATE User u SET u.roles = null")
    void clearAllRoleRelations();
}

我已经尝试过了,但是得到了一个异常 不支持 DML 操作 [UPDATE users.entity.User u SET u.roles = null]

【问题讨论】:

  • 你能展示你的实体吗?
  • 更新方法应该返回一个 int 或 void。也尝试添加@Transactional

标签: java spring-data-jpa many-to-many jpql


【解决方案1】:

放弃@ManyToMany 并为连接表创建一个实体。这样您就可以完全控制删除。

【讨论】:

    【解决方案2】:

    我让它工作了,但是使用本机查询,如果我想在同一个事务中使用它,则需要 entityManager.clear。

        @Modifying
        @Query(nativeQuery = true, value = "DELETE FROM user_role")
        void clearAllRoleRelations();
    
    
      @Autowired
      private EntityManager entityManager;
        
    
      @Test
        public void clearAllRoleRelations() {
    
            //given
            Role roleIn = new Role();
            roleIn.setId(27L);
    
            User userIn = new User();
            userIn.Id(12L);
    
            //do
            roleIn = rolesRepository.save(roleIn);
            userIn = usersRepository.save(userIn);
            userIn.getRoles().add(roleIn);
            usersRepository.save(userIn);
    
            //verify
            usersRepository.clearAllRoleRelations();
    
            //important within the same transaction (native query)
            entityManager.clear();
    
            Optional<User> userOut = usersRepository.findById(userIn.getId());
            assertThat(userOut.isPresent()).isTrue();
            assertThat(userOut.get()).isEqualTo(userIn);
            assertThat(userOut.get().getRoles()).isEmpty();
        }
    

    【讨论】:

      猜你喜欢
      • 2018-04-04
      • 2021-05-25
      • 2017-07-07
      • 2018-06-22
      • 2013-06-17
      • 2011-02-23
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多