我有一个派生自org.ektorp.support.CouchDbDocument的类:

@TypeDiscriminator( value="doc.type == 'TYPE_PRODUCT' )
public class Product extends CouchDbDocument {
....


还有一个存储库类:

public class ProductRepo extends CouchDbRepositorySupport<Product> { ....


存储库类有一个方法:

public List<DocumentOperationResult> executeBulk( Set<Product> bulk ) {
    return db.executeBulk( bulk );
}


该方法用于创建和更新项目。创作进行得很好。但是在更新时,Ektorp抛出此异常:

Caused by: java.lang.IllegalStateException: cannot set id, id already set
    at org.ektorp.support.CouchDbDocument.setId(CouchDbDocument.java:39)
... 18 more


我正在做的是发送一组最初由同一存储库中的视图获取的对象-当然,这些对象的确具有非空ID。当然不会发生这种情况,因为该对象确实具有ID,并且必须更新而不是创建。根据Ektorp文档,db.executeBulk应该处理创建和更新文档。

在CouchDbDocument.setId中引发了异常:

@JsonProperty("_id")
public void setId(String s) {
  Assert.hasText(s, "id must have a value");
  if (id != null && id.equals(s)) {
    return;
  }
  if (id != null) {
    throw new IllegalStateException("cannot set id, id already set");
  }
  id = s;
}


但为什么 ?发送的对象确实具有Id设置(也设置了修订),因此Ektorp应该检测到我们在谈论现有对象,而不是尝试为它们生成新的ID。任何人都知道如何解决此问题,还是在这种情况下放弃Ektorp并通过HTTP获得纯json的解决方案?

(在Jboss 7.1.1.Final,CouchDB 1.2.0,Ektorp 1.2.2上运行的项目)

最佳答案

Ektorp中的批量操作响应处理程序不会检查ID是否已设置。当散装对象扩展CouchDbDocument时,这会导致出现问题,而CouchDbDocument不允许将ID设置一次以上。这种想法是一个错误,它将在Ektorp 1.3.0中修复。

1.3.0之前的解决方法是在Product类中覆盖setId并放宽声明。

09-26 09:11