Search code examples
javacouchdbbulkektorp

BulkUpdate in CouchDB using Java with Ektorp


I have a class which derives from org.ektorp.support.CouchDbDocument:

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

There is also a repository class:

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

The repository class has a method:

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

The method is used for creating and updating items. Creation goes well. But on update, Ektorp throws this exception:

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

What I'm doing is sending a set of objects that were initially fetched by a view in the same repository - and of course the objects do have a not-null Id. This of course should not happen, since the object does have an id and must be updated, not created. According to Ektorp documentation, the db.executeBulk should handle both creating and updating documents.

The exception is being thrown in 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;
}

But why ? The object sent do indeed have the Id set (revision is set too), so Ektorp should detect that we're talking about existing objects and not try to generate a new id for them. Anyone know how to this can be fix, or is the solution to ditch Ektorp and go for pure json over http in this case ?

(Project running on Jboss 7.1.1.Final, CouchDB 1.2.0, Ektorp 1.2.2)


Solution

  • The bulk operation response handler in Ektorp does not check if the id is already set. This causes problems when the bulked object extends CouchDbDocument which does not allow the id to be set more than once. This think this is a bug and it will be fixed in Ektorp 1.3.0

    A workaround until 1.3.0 is to override setId in your Product class and relax the assertion a little bit.