简体   繁体   English

清除与 JPA / JPQL 的多对多关系

[英]Clear ManyToMany Relationship with JPA / JPQL

I have users and roles.我有用户和角色。 And each user can have many roles.每个用户可以有很多角色。

I want to have a bulk operation like remove all User-Roles but keep Users and Roles.我想要进行批量操作,例如删除所有用户角色但保留用户和角色。 So how can i truncate the manyToMany Table only?那么我怎样才能只截断 manyToMany 表呢?

The long way would be findAllUsers -> for each user.roles = new Hashset() -> saveAll(users)很长的路要走 findAllUsers -> for each 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();
}

I have tried this, but get an exception Not supported for DML operations [UPDATE users.entity.User u SET u.roles = null]我已经尝试过了,但是得到了一个异常不支持 DML 操作 [UPDATE users.entity.User u SET u.roles = null]

Ditch the @ManyToMany and create an enitity for the join table. @ManyToMany并为连接表创建一个实体。 This way you'll have full control over the deletion.这样您就可以完全控制删除。

I got it working, but with a native query which then requires an entityManager.clear if i want to use this within the same transaction.我让它工作了,但是使用本机查询,如果我想在同一个事务中使用它,则需要 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();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM