清除与 JPA / JPQL 的多对多关系
Posted
技术标签:
【中文标题】清除与 JPA / JPQL 的多对多关系【英文标题】:Clear ManyToMany Relationship with 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
【参考方案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();
【讨论】:
以上是关于清除与 JPA / JPQL 的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章
与 Play Framework 1.2.5 JPA 的多对多关系