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

Posted

技术标签:

【中文标题】无法从 Spring Boot 应用程序中设置的 DBRef 中删除【英文标题】:Can't remove from DBRef set in Spring Boot application 【发布时间】:2022-01-10 17:19:54 【问题描述】:

我的 Group 对象有一组 @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

【问题讨论】:

Spring Data Mongo 可能很奇怪。 User 是否覆盖 equalshashCode 它不会覆盖它们 打印出remove调用的返回值。 我已经这样做了,请参阅我帖子末尾的打印声明 啊,我明白了。 【参考方案1】:

您似乎习惯了 JPA,它采用各种神奇的魔法手段来确保(在特定事务中)如果您多次看到相同的数据库记录,您会看到相同的 Java 对象,这意味着如果(例如)您从UserRepository 检索到User,然后在其他地方看到Set&lt;User&gt;,那么您在两个地方都有相同的对象。在这种情况下,Collection#remove 会做你想做的事。

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

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

【讨论】:

以上是关于无法从 Spring Boot 应用程序中设置的 DBRef 中删除的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Spring Boot 应用程序中设置 hystrix 仪表板

无法在 Spring Boot 应用程序提供的响应中设置“Access-Control-Allow-Origin”标头

Spring Boot 使用配置文件启用/禁用嵌入式 tomcat

Spring Boot JMS 侦听器:无法刷新目标的 JMS 连接

无法在 Spring Boot 中为 Hikari 设置 keepAlive Time 配置

如何把kotlin+spring boot开发的项目部署在tomcat上