Spring MongoDB - 为什么唯一索引也应用于嵌入式文档?

时间:2016-04-19 13:11:05

标签: java spring mongodb unique-constraint

我有一个带有唯一索引的文档A和另一个嵌入A的文档B.当我尝试将两个文档B保存在其中时,我得到一个双键错误。为什么?不应该在指定的集合中确保唯一索引吗?

A.java

  this.items = [];

  add(item) {
    if(this.items.indexOf(item) > -1) {
      this.items.push(item);
      console.log(this.items);
    }
  }

B.java

@Document(collection = "docsA") 
public class A {
    @Id
    private String id;

    @Indexed(unique = true)  
    private String name;

    private B embed;
}

坚持行动:

@Document(collection="docsB")
public class B {
    @Id
    private String id;

    @Indexed(unique = true)  
    private String name;
}

2 个答案:

答案 0 :(得分:1)

我在你的文档中使用此配置进行测试。

public interface DocsARepository extends MongoRepository<A,Long>{}
public interface DocsBRepository extends MongoRepository<B,Long>{}

今年春季配置

<mongo:mongo id="mongo" />
<mongo:repositories base-package="spring.mongodb.repositories"/>

这个测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "spring.xml")
public class Launcher {

    @Autowired
    DocsBRepository docsBRepository;
    @Autowired
    DocsARepository docsARepository;

   @Test
   public void test1(){

        B b = new B();
        b.setName("BName1");
        b = docsBRepository.save(b);

        A a1 = new A();
        a1.setName("AName1");
        a1.setB(b);
       docsARepository.save(a1); // stored

        A a2 = new A();
        a2.setName("AName2");
        a2.setB(b);
        docsARepository.save(a2); //Dont get any error but record is not inserted
    }

}

运行测试后,我发现对象a2没有被插入到数据库中,并不确定发生了什么,但是如果我在私有B字段上添加@Reference,这就像魅力一样。

> db.docsA.find().pretty()
{
        "_id" : ObjectId("5717acb720e54e20a4d96517"),
        "_class" : "com.koitoer.spring.mongodb.domain.A",
        "name" : "AName1",
        "b" : {
                "_id" : ObjectId("5717acb720e54e20a4d96516"),
                "name" : "BName1"
        }
}
{
        "_id" : ObjectId("5717acb720e54e20a4d96518"),
        "_class" : "com.koitoer.spring.mongodb.domain.A",
        "name" : "AName2",
        "b" : {
                "_id" : ObjectId("5717acb720e54e20a4d96516"),
                "name" : "BName1"
        }
}

我尝试在A类中使用的建议

@Reference
private B b;

使用

<org.mongodb.version>1.5.5.RELEASE</org.mongodb.version>
<org.mongodb.driver>3.0.0-beta3</org.mongodb.driver>
<spring-framework.version>3.2.5.RELEASE</spring-framework.version>

github

中添加此工作示例

答案 1 :(得分:1)

您不能以基于注释的方式来实现它,但是可以通过添加此类Spring的@Configuration来以编程方式实现它:

@Configuration
@DependsOn("mongoTemplate")
public class CollectionsConfig {

    @Autowired
    private MongoTemplate mongoTemplate;

    @PostConstruct
    public void initIndexes() {
        mongoTemplate.indexOps("docsB") // so index is applied only to "docsB" collection
            .ensureIndex(
                new Index().on("name", Sort.Direction.ASC)
        );
    }
}