java - @Document 中的 HashSet,其中实体使用唯一 ID,DuplicatekeyException

标签 java spring-boot spring-data-mongodb

我正在使用 Spring Boot 和 spring data MongoDB(+mongodb-reactive,但我想这对于这个问题并不重要)。对于一些自动生成,我使用 Lombok。

我有一个User实体:

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
...

@Document
@Getter
@Setter
@NoArgsConstructor
@EqualsAndHashCode(exclude = {"friends"})
public class User {
  @Id
  String id;

  @Indexed(unique=true)
  String someOtherIdentifier;

  Set<User> friends;

  ....

  public User(String someOtherIdentifier) {
    this.someOtherIdentifier = someOtherIdentifier;
    this.friends = new HashSet<>();
  }

}

当我现在运行测试并相继创建两个 User 实体时,会引发以下异常:

 E11000 duplicate key error collection: managingService.user index: friends.hashedIdentifier dup key: { : null }; nested exception is com.mongodb.MongoWriteException: E11000 duplicate key error collection: managingService.user index: friends.hashedIdentifier dup key: { : null }))

测试大致如下(我手动测试时也遇到异常):

    @Test
    void create() {
        User entity = new User("1");
        User newEntity = new User("2");

        StepVerifier.create(repository.save(entity))
                .expectNextMatches(entity::equals)
                .verifyComplete();

        StepVerifier.create(repository.save(newEntity))
                .expectNextMatches(newEntity::equals)
                .verifyComplete();

        StepVerifier.create(repository.count()).expectNext(2L).verifyComplete();
    }

我发现问题是由 friends 集合引起的,其中第二个实体在该集合内具有相同的 User。当然,不同的用户可以有相同的 friend ,所以在这个集合中,它不应该检查唯一的ID。 非常感谢任何有关如何解决此问题的帮助!

最佳答案

@Indexed注释也会根据 Set<User> 进行评估产生两个唯一索引。

"someOtherIdentifier" : 1
"friends.someOtherIdentifier" : 1

请考虑disable auto indexes并通过 IndexOperations 使用手动索引相反。

Index index = new Index("someOtherIdentifier", Direction.ASC).unique();
template.indexOps(User.class).ensureIndex(index);

关于java - @Document 中的 HashSet,其中实体使用唯一 ID,DuplicatekeyException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60722244/

相关文章:

java - 方法返回了一个值,但该值未正确传递

java - Findbugs 在并行 Gradle 构建中记录太多

java - 如何使用另一种 SOAP 应用程序来使用另一种 SOAP 应用程序

spring-boot - Sleuth 不显示跟踪 ID 和跨度 ID

mongodb - 使用 MongoTemplate 时是否可以动态设置特定查询的读取首选项?

java - Spring Data MongoDB 使用 DBRef 按嵌套属性(非 ID)查找

java - 在全局范围内限制 Play 框架的 Java 堆空间

java - Spring MVC 中模型对象未传递给 jsps - InternalResourceView - renderMergedOutputModel

java - Spring JPA 不为实体创建表

java - 带有 ObjectID 的 Spring Data Mongo 自定义存储库查询