0
votes

Is there a recommended way to go about dealing with documents that don't have the _class field with spring-data-couchbase( if there is one)? Trying it simply just throws an exception as expected.

Edit: Apologies if this was a bit too vague, let me add a bit more context. I want to fetch data from couchbase for some student by name, let's say . The repository looks something like -

@Repository

public interface StudentRepository extends CouchbaseRepository {

Optional<StudentDocument> findByName(String name);

}

Now the documents in couchbase don't have the _class field OR say if we are entering a different "key" and "value" for _class field as we don't want to rely on it, so this method fails. I sort of hacked a workaround for this using -

`

@Override
public Student getStudent(String name) {
    N1qlQuery query = N1qlQuery.simple(String.format("select *, META().id AS _ID, META().cas AS _CAS" +
            " from student where name = \'%s\';", name));
    return Optional.ofNullable(studentRepository.getCouchbaseOperations()
            .findByN1QL(query, StudentWrapper.class)
            .get(0))
            .map(StudentWrapper::getStudent)
            .orElseGet(() -> {
                throw new HttpClientErrorException(HttpStatus.NOT_FOUND);
            });
}

`

I was wondering if there is an alternate way of achieving this

1
What do you mean by dealing? In theory, you will always use your _class filter, so you won't get any documents which don't have the type you have specified. - deniswsrosa
Well, one scenario is when dealing with legacy documents that were written by a service that was using a framework other than spring-boot . Also, it seems a bit weird to bind the location of the class with how it gets deserialized using the _class field to me ( I understand there might have been limitations because of Spring Data interface contracts). Passing it the type I want it to be transformed to would be a pretty good option imo - silver-soul
You don't need to use the _class attribute, you can difine your own: stackoverflow.com/questions/55098306/… . - deniswsrosa
But that will help me write a different value for the key and value in json (for the _class field). But I have not been able to figure out how that will work when trying to read the data from couchbase. - silver-soul

1 Answers

0
votes

While using Spring spEL, Couchbase will automatically include the _class (or whatever attribute you have defined as your type) for you:

public interface AreaRepository extends CouchbaseRepository<Area, String> {
   //The _class/type is automatically included by Couchbase 
    List<Area> findByBusinessUnityIdAndRemoved(String businessId, boolean removed);
}

However, if you want to use N1QL, you have to add the #{#n1ql.filter} :

public interface BusinessUnityRepository extends CouchbaseRepository<BusinessUnity, String>{

    @Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and companyId = $2 and $1 within #{#n1ql.bucket}")
    BusinessUnity findByAreaRefId(String areaRefId, String companyId);

}

the #{#n1ql.filter} will automatically add the filter by type for you.