Nikhil
Nikhil

Reputation: 374

_class property in CouchBase

I have a document stored in Couchbase.

{
  "a": {
    "b": {
      "key":"Value"
    },
 "_class":"com.nikhil.model"
  },
    "c":{
      "d":{
        "key":"value"
       },
  // _class is missing here
     },
      "_class": "com.nikhil.model"
 }

Here as you can see I don't have an _class inside the "d" in the doucument because of this I am not able to get this document. An object mapping exception came. _class is used to map the nested object of couchbase to the model required for mapping but inside the "c" object I don't have this _Class property that is why a mapping exception comes. Is there any fix for this?

Upvotes: 0

Views: 1006

Answers (3)

awasum
awasum

Reputation: 31

If you are using Spring boot, you need to override the typekey() method in the Couchbase Config file which extends AbstractCouchbaseConfiguration and return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE. This will replace your _class with javaClass string in the documents stored in Couchbase Server. I hope this helps.

@Configuration
public class RemoteCouchbaseConfiguration extends AbstractCouchbaseConfiguration {

    @Value("${couchbase.host}")
    private String host;

    @Value("${couchbase.bucket.bucketName}")
    private String bucketName;

    @Value("${couchbase.bucket.password}")
    private String password;

    @Override
    protected List<String> getBootstrapHosts() {
        return Arrays.asList(this.host);
    }

    @Override
    protected String getBucketName() {
        return this.bucketName;
    }

    @Override
    protected String getBucketPassword() {
        return this.password;
    }

    @Override
    public String typeKey() {
        return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE;
    }
}

Upvotes: 2

deniswsrosa
deniswsrosa

Reputation: 2460

Looks like you are using Couchbase with Spring Data, the easiest way is to return a projection:

@Override
public List<UserVO> getUsers(String companyId, List<String> userIds) {

    String queryString =  "SELECT meta(t).id as id, t.login as login, t.firstName as firstName from " + getBucketName() + " t where t."+getClassFilter()+" "
            + " and t.companyId = '" + companyId + "' and t.isEnabled = true and t.isVisible = true "
            + " and meta(t).id in ["+userIds.stream().map(e->"'"+e+"'").collect( Collectors.joining( "," )) +"]";
    N1qlParams params = N1qlParams.build().consistency(ScanConsistency.NOT_BOUNDED).adhoc(true);
    ParameterizedN1qlQuery query = N1qlQuery.parameterized(queryString, JsonObject.create(), params);

    return   userRepository.getCouchbaseOperations().findByN1QLProjection(query, UserVO.class);
}

Upvotes: 1

Matthew Groves
Matthew Groves

Reputation: 26141

You could add _class to it using an UPDATE N1QL statement like this:

UPDATE mybucket b
SET b.c.d._class = 'com.foo.bar'
WHERE b.c.d IS NOT MISSING
AND b.c.d._class IS MISSING

That will update any document that has a 'd' object within a 'c' object but doesn't have a '_class' within the c object.

Upvotes: 0

Related Questions