Search code examples
couchbasespring-data-couchbase

Repository uses N1QL


I'm getting the following exception:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'answerRepository': Invocation of init method failed; nested exception is org.springframework.data.couchbase.core.UnsupportedCouchbaseFeatureException: Repository uses N1QL

I'm using Spring 4.2.0.RELEASE with spring-data-couchbase 2.0.0.M1 against Couchbase 2.5.1 enterprise edition (build-1083)

I can't see any explanation in the doc for this error.

Here is the repository:

public interface AnswerRepository extends BaseRepository<Answer, String> {

  final static String DESIGN_DOCUMENT = "answers";

  @View(viewName = "answers_by_quizId_startTime", designDocument = DESIGN_DOCUMENT)
  public List<Answer> findByQuizIdAndStartTime(String quizId, long startTime);

  Answer findByUuid(String uuid);

}

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID>  {
}

Maybe my Couchbase server does not support this feature, whereas my repository expects it.

I might need to code my repository differently.

It's too bad it doesn't say which method is the invalid one here.

Or it is my using of the CrudRepository in the base class ?

I wonder how to find out which views it expects to find in my Couchbase server.


Solution

  • Repositories in Spring Data Couchbase 2.0 rely almost exclusively on Views and N1QL. A good chunk of the new features in this version are made possible by N1QL, which is now the default mechanism Spring Data uses for things like "query derivation" (implementing a repository method by producing some sort of query that is derived from the method name).

    Couchbase Server 2.5.1 doesn't have access to N1QL (which came with Couchbase Server 4.0 and of course also in the brand new 4.1 version).

    If you want Spring Data to implement findByUuid for you, you'll have to annotate that method with @View and create the appropriate view that emits uuids from your Answer documents.

    View query derivations are heavily restricted and give you more work since you have to write the correct map function:

    • a repository method based on a view can only query with one criteria.
    • you have to create your view correctly, emitting the correct keys corresponding to the criteria you'll query with.
    • you have to create one view per entity class, restricting the view to only emit if the "_class" field in the JSON matches said entity (note: this field can be renamed in the configuration so make sure to use the relevant one).

    So that means that your findByQuizIdAndStartTime cannot work either. You may have to implement this (and maybe findByUuid) in the BaseRepository, relying on the CouchbaseTemplate and using its findByView method (or even queryView as a last resort).

    The UnsupportedCouchbaseFeatureException is mentioned in the M1 doc chapter 7 (on N1QL based querying).

    See also the section on view query derivation further down the documentation.