Replace PersistentEntity.doWithProperties(…) and .doWithAssociations(…) with stream processing using PersistentEntity.getPersistentProperties() and PersistentEntity.getAssociations().
Motivation
----------
AbstractCouchbaseDataConfiguration was removed and
AbstractCouchbaseConfiguration was made the only configuration support
which implemented CouchbaseConfigurer. This broke integration with
Spring boot as they used CouchbaseConfigurer to auto configure client
initialization properties.
Changes
-------
Bring back support for AbstractCouchbaseDataConfiguration which allows the use
of CouchbaseConfigurer. Also added a similar configuration support for reactive
data repositories. Common beans between reactive and blocking are implemented
in CouchbaseConfigurationSupport class. The existing tests in
AbstractCouchbaseDataConfigurationTest does test this scenario. However the
previous commit had also changed the test because of the unawareness of spring
boot integration.
Results
-------
It is now possible to configure SDC with CouchbaseConfigurer instead of
only having to extend from AbstractCouchbaseConfiguration.
- Adds experimental support for reactor types in reactive CRUD and Sorting
repositories using RxJava1Template
- Refactor configuration and query classes to be reusable by reactive repositories
Original pull request: #130.
Removed the dynamic return type obtained from the ResultProcessor held in a query implementation field as this breaks thread safety. We now hand the type to read into the execution methods.
Adapted test cases accordingly and removed a bit of mocking.
Original pull request: #122.
Used the result processor projecting information to just fetch the selected fields and again to post process results to projection object/interfaces.
Added test for projection using DTO.
Original pull request: #122.
Defining <couchbase:env/> in XML configuration was causing a double
instantiation of DefaultCoreEnvironment, with subsequent warning in
logs:
[main] WARN c.c.client.core.env.CoreEnvironment - More than 1 Couchbase
Environments found (2), this can have severe impact on performance and
stability. Reuse environments!
This brings better performance when querying large views. Instead of
looping on a synchronously acquired list of documents to produce a list
of entities, the async API can be used internally to:
- query the view
- fetch the documents
- map each document to an entity
- collect into a List
One can then block on that Observable to get and return the List as
usual.
If the MappingCouchbaseConverter strict mode is enabled and no annotation is present, the property will not be eligible for document mapping.
This allows to specifically ignore some attributes in Couchbase only. For generally ignoring attributes in any Spring Data backing store, prefer the standard `@Transient`.
Closes#112
This change takes the `Version` annotated field into account when performing a `save` (either in the `CouchbaseTemplate` or transitively in a `CouchbaseRepository`).
Having such a field with a non-zero value means that a CAS is available, activating optimistic locking. Version 1.4 and below of Spring Data Couchbase was taking this CAS into account, whereas in 2.0 we switched to using `upsert` internally, which ignores the CAS.
This change brings the behavior of `save` (when there's a non-zero CAS) closer to what was observed in 1.4 versions: an `OptimisticLockingFailureException` can now be raised in case of CAS mismatch.
This commit adds support for auditing via the use of the four annotations (CreatedBy, LastModifiedBy, CreationDate, LastModificationDate), enabled via the EnableCouchbaseAuditing annotation.
As couchbase entities MUST have an id, the only case where the creation event can be detected is when the entity has a Version annotated field.
This commit allows to separate creation of beans dedicated to Spring Data Couchbase from the ones that can be made more common (SDK instances) and now can be provided externally through a a strategy interface, `CouchbaseConfigurer`.
Rather than having to extend a few methods from the base Configuration
class, `CouchbaseConfigurer` represents all the components that the Spring Data integration requires.
Configuration is based on Document annotation. When read of document takes place then touch action is executed on document. It is an asynchronous action so it does not block read. It is executed only on single reads (not view-based or N1QL-based ones).
In addition to annotating the repository with xxxIndexed annotations, user must now opt-in to the feature by redefining the indexManager bean in the configuration. This is so production use of this feature is actively discouraged.
Choice of placeholder "mode" is determined by the syntax used inside the query, early during repository instantiation.
An IllegalArgumentException is thrown if both named and positional parameters are used.
The generated view's default map function now emits meta.id so that CRUD findAll(ids) works.
The default value for the view name is now "all".
The ViewIndexed isn't documented as applicable to METHODs (deferred feature).
This change allows simple projections to types long, boolean, String when an inline N1QL query uses an aggregation function like AVG, COUNT.
The projection's result must be a single row with a single key/value pair in the N1QL response. Only the value gets returned.
This commit ensures that methods in the template and the repository base classes are correctly ignoring documents that have been deleted but are still identified by the view due to using weak consistency (Stale.TRUE).
FindByView in template now ignores null rows in its result list. It also correctly forces the includeDocs parameter in order not to risk a bad transcoding of the document (javadoc clarified).
DeleteAll in the repository CRUD implementation will correctly detect attempts at deleting a non-existing document (DocumentDoesNotExistException is also correctly mapped to a Spring Data exception now).
DeleteAll behavior with DataRetrievalFailureException is tested in RepositoryIndexUsageTest.
The CRUD methods that are backed by a view in SimpleCouchbaseRepository now take the default view consistency into account.
This includes findAll(), findAll(keys), count() and deleteAll().
PagingAndSortingRepository findAll methods already took the default N1QL consistency into account.
This is verified in an unit test and has been made more explicit in the repository documentation.
This fixes the fact that EnableCouchbaseRepository(repositoryBaseClass = Something.class) was ignored.
Now using reflection to choose the target implementation. Note that custom base classes MUST extend SimpleCouchbaseRepository (or its subclass N1qlCouchbaseRepository).
An example in the form of an integration test has been added in src/integration/java/org/springframework/data/couchbase/repository/base/RepositoryBaseTest.java.
So far with geo queries a bounding box approximation was performed on Circle and Polygon queries (since Couchbase internally only supports Bounding Box queries).
It was confusing since in previous iteration it was up to the user to remove these false positives "after the fact" in code calling the repository.
This change allows for the framework to retain enough information to perform false positives elimination automatically and transparently for the user.
The configuration step made it look like a new mapping was necessary in overrides, whereas it is actually possible and clearer to mutate the base mapping.
Added a convenience method to get the MappingContext from the repository mapping.
Main indexes (ie indexes that can be used by repositories to retrieve ALL the documents of a particular entity type) are covered.
Repository interfaces can be annotated with an annotation for each type of main index that can be automatically created.
The IndexManager is responsible for creating said indexes (potentially skipping creation if an index is already in place, or if the IndexManager has been configured to skip it, see constructor).
Since IndexManager is created as a bean (either in JavaConfig or xml), there can be a different instance eg. in Prod vs Dev.
Added doc and integration test.
Renamed package core.view to core.query since it now contains various non-view related annotations and classes.
Detection whether or not reduce should be activated is now centralized. Triggers are:
- using the count prefix instead of find in method name
- setting reduce = true in the View annotation explicitly.
The reduce can thus be returning any kind of value (added an integration example with _stats), which is now properly documented.
Added the step of parsing SpEL expressions delimited by ${ } in StringN1qlBasedQuery, then the actual evaluation of each expression.
Refactored StringN1qlBasedQuery to use SpEL across the board, including for N1QL specific placeholders (SELECT-FROM, WHERE filter, etc...).
Refactored StringN1qlBasedQuery to use local methods rather than static methods, and amended the unit tests accordingly (using mocks).
Refactored getStatement and getCountStatement so they can see the parameters passed in at runtime.
Added unit tests + integration test.
Added SpEL support example in documentation.