We now no longer emit an exception via SimpleReactiveMongoRepository.findOne(Example) if the query completes without yielding a result. Previously findOne(Example) emitted a NoSuchElementException if the query returned no result.
Original pull request: #541.
Turn instance methods into static ones where applicable. Avoid parameter type array cloning where possible.
Add reference to rework stack-trace inspection in order to throw ClientSessionException. Migrate MongoPersistentEntityIndexCreatorUnitTests to AssertJ. Add tests to verify simple session proxy wrapping on subsequent MongoDbFactory.withSession(…) calls.
Guard ClientSession tests with replica set rule. Remove unused code. Add non-null guards. Add missing Nullable annotations. Slightly tweak Javadoc and reference documentation.
Original pull request: #536.
We now support ClientSession via MongoOperations and ReactiveMongoOperations. Client sessions introduce causal consistency and retryable writes. A client Session can be either provided by application code or managed by specifying ClientSessionOptions. Binding a ClientSession via MongoOperations.withSession(…) provides access to a Session-bound MongoOperations instance that associates the session with each MongoDB operation.
ClientSession support applies only to MongoOperations and ReactiveMongoOperations and is not yet available via repositories.
ClientSession session = client.startSession(ClientSessionOptions.builder().causallyConsistent(true).build());
Person person = template.withSession(() -> session)
.execute(action -> {
action.insert(new Person("wohoo"));
return action.findOne(query(where("id").is("wohoo")), Person.class);
});
session.close();
Original pull request: #536.
Switched to ClassUtils.isAssignableValue(…) in getPotentiallyConvertedSimpleRead(…) as it transparently handles primitives and their wrapper types so that we can avoid the superfluous invocation of the converter infrastructure.
We now export composable repositories through our CDI extension. Repositories can now be customized either by a single custom implementation (as it was before) and by providing fragment interfaces along their fragment implementation.
This change aligns CDI support with the existing RepositoryFactory support we provide within a Spring application context.
We previously used MongoTemplate.insertAll(…) which determines the collection to insert the individual elements based on the type, which - in cases of entity inheritance - will use dedicated collections for sub-types of the aggregate root. Subsequent lookups of the entities will then fail, as those are executed against the collection the aggregate root is mapped to.
We now rather use ….insert(Collection, String) handing the collection of the aggregate root explicitly.
Extend copyright license years. Slightly reword documentation. Use IntStream and insertAll to create test fixture.
Original pull request: #532.
Related pull request: #531.
We now use _id lookup for remove operations that query with limit or skip parameters. This allows more fine grained control over documents removed.
Original pull request: #532.
Related pull request: #531.
We now use AbstractMongodbQuery.fetch() instead of AbstractMongodbQuery.fetchResults() to execute MongoDB queries. fetchResults() executes a find(…) and a count(…) query. Retrieving the record count is an expensive operation in MongoDB and the count is not always required. For regular find(…) method, the count is ignored, for paging the count(…) is only required in certain result/request scenarios.
Original Pull Request: #529
We now return the first result when executing findFirst/findTop queries. This fixes a glitch introduced in the Kay release throwing IncorrectResultSizeDataAccessException for single entity executions returning more than one result, which is explicitly not the desired behavior in this case.
Original pull request: #530.
We now avoid calling ….inCollection(…) with a fixed, one-time calculated collection name to make sure we dynamically resolve the collections. That's necessary to make sure SpEL expressions in @Document are evaluated for every query execution.
Allow reuse of builders instead of resetting state after MessagePropertiesBuilder.build(). Use Java streams where possible. Slightly reorder fields to match constructor argument order. Add generics to request builders and introduce typed builder(…) methods to retain builder generics. Add builder for TailableCursorRequest.
Introduce factory method on MessageListenerContainer for container creation. Change Subscription.await() to use CountDownLatch instead of polling to integrate better with ManagedBlocker.
Add protected constructors to options and builder classes. Add assertions where appropriate. Move task classes into top-level types. Extract methods. Typo fixes in reference docs.
Original pull request: #528.
As of MongoDB 3.6, Change Streams allow application to get notified about changes without having to tailing the oplog.
NOTE: Change Stream support is only available with replica sets or a sharded cluster.
Change Streams can be subscribed to with both the imperative and the reactive MongoDB java driver. It is highly recommended to use the reactive variant as it is less resource intensive. However if you do not feel comfortable using the reactive API for whatever reason, you can sill obtain the change events via a Messaging concept already common in the Spring ecosystem.
== Change Streams - Sync ==
Listening to a Change Stream using a Sync Driver is a long running, blocking task that needs to be delegated to a separate component.
In this case we need to create a MessageListenerContainer first which will be the main entry point for running the specific SubscriptionRequests.
Spring Data MongoDB already ships with a default implementation that operates upon MongoTemplate and is capable of creating and executing Tasks for a ChangeStreamRequest.
MessageListenerContainer container = MessageListenerContainer.create(template);
container.start();
MessageListener<ChangeStreamDocument<Document>, User> listener = System.out::println;
ChangeStreamRequestOptions options = new ChangeStreamRequestOptions("user", ChangeStreamOptions.empty());
Subscription subscription = container.register(new ChangeStreamRequest<>(listener, options), User.class);
== Change Streams - Reactive ==
Subscribing to Change Stream via the reactive API is clearly more straight forward. Still the building blocks like ChangeStreamOptions remain the same.
Aggregation filter = newAggregation(User.class, match(where("age").gte(38));
Flux<ChangeStreamEvent<User>> flux = reactiveTemplate.changeStream(filter), User.class, ChangeStreamOptions.empty());
== Tailable Cursors - Sync ==
This commit also adds support for tailable cursors using the synchronous driver to be used with capped collections:
MessageListenerContainer container = MessageListenerContainer.create(template);
container.start();
TailableCursorRequestOptions options = TailableCursorRequestOptions.builder()
.collection("user")
.filter(query(where("age").is(7)))
.build()
container.register(new TailableCursorRequest<>(messageListener, options, User.class));
Original pull request: #528.
Convert lineendings from CRLF to LF. Reduce validator implementations visibility to package. Extend Javadoc. Slight rewording in reference documentation.
Original pull request: #525.
Related pull request: #511.
Related ticket: DATACMNS-1835.
Remove ValidationAction/Level and ValidationOptions duplicates. Rename ValidatorDefinition to Validator and Validator to ValidationOptions.
Update and rename some of the tests. Also make sure to run the created validator document through the QueryMapper for value conversion and potential field mappings. Streamline Validator usage by providing plain Document and JsonSchema validator options next to the Criteria based one.
Finally update the reference documentation.
Original pull request: #525.
Related pull request: #511.
Related ticket: DATACMNS-1835.
Extended the CollectionOptions with a ValidationOptions property which
corresponds to the MongoDB createCollection() parameters. A validator
object can be defined using the Criteria API, or by writing a custom
provider.
Original pull request: #511.
Related pull request: #525.
Related ticket: DATACMNS-1835.