无法从 Spring 启动应用程序中设置的 DBRef 中删除

Can't remove from DBRef set in Spring Boot application

我的组对象有一组@DBRef 用户,每个用户同样有一组@DBRef 组:

public class Group {
    @Id
    private String id;
    @Indexed(unique = true)
    private String name;
    @DBRef(lazy=true)
    private Set<User> users;

    //...
}
public class User {
    @Id
    private String id;
    @Indexed(unique = true)
    private String email;
    private String password;
    private String role;
    @DBRef(lazy = true)
    private Set<Group> groups;
    //...
}

当我删除用户时,我当然必须将他从他的组中删除:

Set<Group> subscribedGroups = userRepository.findByEmail(email).getGroups();
for (Group g : subscribedGroups) {
    Set<User> users = g.getUsers();
    users.remove(user);
    g.setUsers(users); // not sure if this line is necessary but it doesnt work regardless
    groupRepository.save(g);
}

这是行不通的。 remove(user) 由于某种原因返回 false。它应该工作;我打印了 users 的每个成员的 ID,然后是 user.getId(),然后是 remove(user) 的结果:

List of users:
61abd6f1c81ab948c31641f2

User to delete: 61abd6f1c81ab948c31641f2
Result of removal: false

您似乎已经习惯了 JPA,它采用各种神奇的方法来确保(在特定事务中)如果您不止一次看到相同的数据库记录,您会看到 相同的 Java object,这意味着如果(例如)你从 UserRepository 中检索到一个 User 然后在其他地方看到一个 Set<User>,你有 两个地方的相同对象。在这种情况下,Collection#remove 将执行您想要的操作。

MongoDB 支持不同:它只是将 POJO 映射为被动数据对象。这意味着除非您的实体 class 实现了 equalshashCode,否则集合实现(以及其他任何东西)不会认为它们相等。您需要根据 ID 执行类似 removeIf 的操作。

(顺便说一句,这就是为什么您需要对大多数存储库实现调用 repo.save(changed),即使您没有专门使用 JPA。)