我尝试从ManyToMany-Relation中删除一个实体,但是在通过我的存储库保存了父实体之后,什么都没有发生。
UserRepository:
public interface UserRepository extends EntityGraphJpaRepository<User, Long> {
User findByEmailIgnoreCase(String email);
Page<User> findBy(Pageable pageable);
User findByEmail(String name, com.cosium.spring.data.jpa.entity.graph.domain.EntityGraph entityGraph);
}
AbstractEntity
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
private static final long serialVersionUID = -2523912452050488728L;
@Id
@GeneratedValue
private Long id;
@Version
private int version;
public Long getId() {
return id;
}
public int getVersion() {
return version;
}
@Override
public int hashCode() {
if (id == null) {
return super.hashCode();
}
return 31 + id.hashCode();
}
@Override
public boolean equals(Object other) {
if (id == null) {
// New entities are only equal if the instance if the same
return super.equals(other);
}
if (this == other) {
return true;
}
if (!(other instanceof AbstractEntity)) {
return false;
}
boolean test = id.equals(((AbstractEntity) other).id);
return id.equals(((AbstractEntity) other).id);
}
}
用户实体
@NamedEntityGraphs(value = {
@NamedEntityGraph(name = "User.roles.groups", attributeNodes = {
@NamedAttributeNode("roles"),
@NamedAttributeNode("groups")
})
})
@Entity(name="userInfo")
public class User extends AbstractEntity {
@ManyToMany(mappedBy = "users", fetch = FetchType.LAZY, cascade= {CascadeType.PERSIST, CascadeType.MERGE}) //inverse side
private Set<Role> roles = new HashSet<Role>();
public void addRole(Role role) {
this.roles.add(role);
role.getUsers().add(this);
}
public void removeRole(Role role) {
this.roles.remove(role);
role.getUsers().remove(this);
}
//...
}
RoleEntity:
public class Role extends AbstractEntity {
@ManyToMany(fetch = FetchType.LAZY, cascade= {CascadeType.PERSIST,CascadeType.MERGE}) //owning side
@JoinTable(
name = "role_user",
joinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
private Set<User> users = new HashSet<User>();
UserService:
@Service
public class UserService implements CrudEntityServiceInterface{
private UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void save(User user) {
this.userRepository.saveAndFlush(user);
}
public User updateRolesForUser(User user,Set<Role> roleItems,RoleService roleService) {
Set<Role> rolesToRemove = new HashSet<Role>();
for(Role oldRole: user.getRoles()) {
//remove roles which are deselected
if(!roleItems.contains(oldRole)) {
Optional<Role> oldRoleLoaded = (roleService.getRepository()).findById(oldRole.getId(),EntityGraphs.named("Role.users.groups"));
rolesToRemove.add(oldRoleLoaded.get());
}
}
rolesToRemove.forEach(x -> user.removeRole(x));
//added selected roles
roleItems.forEach(x -> {
Optional<Role> xLoaded = (roleService.getRepository()).findById(x.getId(),EntityGraphs.named("Role.users.groups"));
user.addRole(xLoaded.get());
} );
return user;
}
//...
}
并且在我的控制器中,我称呼类似
user = userService.updateRolesForUser(user,roles,roleService);
userService.save(user);
我必须使用entityGraph,因为我不想使用Fetch.Eager。
您有什么线索为什么我不能从用户中删除角色?我也尝试过Cascade.Remove-但这不能解决问题,并且是不正确的做法,我想。
编辑:当我打电话时
rolesToRemove.forEach(x -> {user.removeRole(x); roleService.save(x);});
我要从该关系中删除的实体已删除。但是我认为通过CascadeType.Persist在userRepository上调用save可以更新用户的所有内容?为什么我还要另外呼叫保存角色?
旧问题,但角色控制ManyToMany关系。如果您希望对关系保持更改,则必须更新角色对象,而不是用户端。