Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Spring Data Moore and Beyond

Spring Data Moore and Beyond

What's new in recent Spring Data release train Moore and what the team has planned for the next one (aka Neumann).

Christoph Strobl

November 16, 2019
Tweet

More Decks by Christoph Strobl

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Spring Data … what? Spring Data’s mission is to provide 
 a familiar and consistent, 
 Spring-based programming model for data access 
 while retaining the special traits of the underlying data store.
  2. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface StarshipRepository extends CrudRepository<Starship, String> { Optional<Starship> findById(String id); List<Starship> findByName(String name); } Spring Data … what? JDBC ApacheTM Cassandra JPA
  3. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov 375 Days 700+ Issues 16 Modules
  4. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov 16 Modules 375 Days 700+ Issues Kotlin Performance Reactive
  5. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov 16 Modules 375 Days 700+ Issues Kotlin Performance Reactive New Features Coroutines & Flow Declarative Reactive Transactions 60% faster finder methods*
 * for eg. JPA single attribute finder like 'findByTitle'
  6. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov Reactive
  7. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov Reactive Declarative Transactions
  8. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Transactions public Mono<Process> doSomething(Long id) { return template.inTransaction().execute(action -> { return findById(id) .flatMap(it -> start(action, it)) .flatMap(it -> verify(it)) .flatMap(it -> finish(action, it)); }).next(); } Flux<T> Mono<T>
  9. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Declarative Transactions @EnableTransactionManagement class Config extends AbstractReactiveMongoConfiguration { @Bean ReactiveTransactionManager mgr(ReactiveMongoDatabaseFactory f) { return new ReactiveMongoTransactionManager(dbFactory); } // ... } New in Moore
  10. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Declarative Transactions @Transactional public Mono<Process> doSomething(Long id) { return findById(id) .flatMap(it -> start(template, it)) .flatMap(it -> verify(it)) .flatMap(it -> finish(template, it)); } template.inTransaction().execute(… .next() start(action,… finish(action,… New in Moore
  11. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov Reactive Elasticsearch
  12. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Why not…? public Mono<SearchResponse> search(SearchRequest request) { return Mono.create(sink -> client.searchAsync(request, options, new ActionListener<>() { @Override public void onResponse(SearchResponse searchResponse) { sink.success(searchResponse); } @Override public void onFailure(Exception e) { sink.error(e);
  13. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Elasticsearch Client class Config extends AbstractReactiveElasticsearchConfiguration { @Bean @Override public ReactiveElasticsearchClient reactiveClient() { return ReactiveRestClients.create(localhost()); } } based on WebClient New in Moore
  14. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Elasticsearch Template @Autowired ReactiveElasticsearchTemplate template; //... Criteria criteria = new Criteria("topics").contains("spring") .and("date").greaterThanEqual(today()) CriteriaQuery query = new CriteriaQuery(criteria); Flux<Conference> result = template.find(query, Conference.class); New in Moore
  15. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Elasticsearch Repository interface ConferenceRepo extends ReactiveCrudRepository<…> { Flux<Conference> findAllByKeywordsContainsAndDateAfter(…); } @Autowired ConferenceRepo repo; //… Flux<Conference> result = repo.findAllByKeywordsContainsAndDateAfter("spring", today()); New in Moore
  16. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov Reactive Querydsl
  17. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Querydsl interface Repository extends …, QuerydslPredicateExecutor<Customer> QCustomer.customer.lastname.eq("Matthews")
  18. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Querydsl interface Repository extends …, QuerydslPredicateExecutor<Customer> @Autowired Repository repo; //… Predicate predicate = QCustomer.customer.lastname.eq("Matthews"); List<Customer> result = repo.findAll(predicate);
  19. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Querydsl interface Repository extends …, ReactiveQuerydslPredicateExecutor<…> @Autowired Repository repo; //… Predicate predicate = QCustomer.customer.lastname.eq("Matthews"); Flux<Customer> result = repo.findAll(predicate); New in Moore
  20. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Kotlin
  21. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Type-Safe Queries Kotlin
  22. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Kotlin val people = operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .all() Kotlin Extension
 to avoid `is` (…
  23. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Kotlin val people = operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .all() List<Person> people = operations.query(Person.class) reified type parameter
  24. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Kotlin type-safe query DSL val people = operations.query<Person>() .matching(query(Person::lastname isEqualTo "Matthews")) .all() where("lastname") .isEqualTo("Matthews") New in Moore New in Moore
  25. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Coroutines & Flow Kotlin
  26. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Kotlin operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .doOnNext { … } .subscribe() New in Moore
  27. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Coroutines val result = runBlocking { operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .awaitSingle() } New in Moore
  28. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Flow val result = runBlocking { operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .asFlow().toList() } New in Moore
  29. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov Performance
  30. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ JMH Java Microbenchmark Harness baseline native code path Derived Query Annotated Query Transactional Query Spring Data
  31. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ JMH @Benchmark public void findByTitle(Blackhole sink) { Query q = em.createQuery("select b from Book b where b.title = ?1"); q.setParameter(1, "title0"); sink.consume(query.getSingleResult()); } @Benchmark public void repositoryFindByTitle(Blackhole sink) { sink.consume(repository.findDerivedByTitle("title0")); } native code path Spring Data
  32. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 33 Ops/sec* *spring-data-jpa
 in memory H2 SQL
 Mac Book Pro 3.2 GHz RC1 RC2 findAll 52.213 61.244 findByTitle 74.192 123.040 repositoryByTitle 70.344 120.333 repositoryByTitleDeclared 65.236 111.760
  33. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 34 RC1 RC2 findAll 52.213 61.244 findByTitle 74.192 123.040 repositoryByTitle 70.344 120.333 repositoryByTitleDeclared 65.236 111.760 Ops/sec* *spring-data-jpa
 in memory H2 SQL
 Mac Book Pro 3.2 GHz
  34. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 35 RC1 RC2 findAll 52.213 61.244 findByTitle 74.192 123.040 repositoryByTitle 70.344 120.333 repositoryByTitleDeclared 65.236 111.760 Ops/sec* *spring-data-jpa
 in memory H2 SQL
 Mac Book Pro 3.2 GHz Clean Room Scenario! Almost each and every performance benchmark avoids any kind of overhead whatsoever.
  35. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov New Features
  36. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov New Features Entity Callback API
  37. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Modifying Entities via Events @Component class MongoListener extends AbstractMongoEventListener<Person> { @Override public void onBeforeSave(BeforeSaveEvent<Person> event) { event.getDocument().put(…) } } already converted (store specific)
 Person representation
  38. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Modifying Entities via Callbacks @Bean BeforeSaveCallback<Person> beforeSave() { return (entity, document) -> { document.put(…); return entity; } } already converted (store specific)
 Person representation New in Moore
  39. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Modifying Entities via Callbacks @Bean BeforeConvertCallback<Person> beforeConvert() { return (entity, collection) -> { return entity.withId(…); } } new Person object with and id set @Bean BeforeSaveCallback<Person> beforeSave() { return (entity, document) -> {…} } already converted (store specific)
 Person representation with changes applied New in Moore
  40. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Modifying Entities via Callbacks @Bean ReactiveBeforeConvertCallback<Person> beforeConvert() { return (entity, collection) -> { return Mono.just(entity.withId(…)); } } New in Moore
  41. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov New Features Declarative Aggregations
  42. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Aggregation Framework API {$group:{_id:'$cust_id',total:{$sum:'$amount'}}} newAggregation(Order.class, group(
 Fields.from(Fields.field("_id", "cust_id"))) .sum("amount").as("total") );
  43. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
  44. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ MongoDB Aggregations {$group:{_id:'$cust_id',total:{$sum:'$amount'}}} newAggregation(Order.class, group(
 Fields.from(Fields.field("_id", "cust_id"))) .sum("amount").as("total") );
  45. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ @Aggregation(" ") Declarative Aggregations {$group:{_id:'$cust_id',total:{$sum:'$amount'}}} New in Moore
  46. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ interface OrderRepository extends CrudRepository<Order, Long> { @Aggregation(" ") List<TotalByCustomer> totalByCustomer(Sort sort); @Aggregation(pipeline={ "{$match:{customerId:?0}}", "{$count:total}"}) Long totalOrdersForCustomer(String customerId); } Declarative Aggregations {$group:{_id:'$cust_id',total:{$sum:'$amount'}}} { "total" : 101 } New in Moore
  47. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov New Features Multiple out parameters JPA
  48. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Stored Procedures @NamedStoredProcedureQuery(name = "User.s1p", procedureName = "s1p", parameters = { @StoredProcedureParameter(mode = IN, name = "in_1", type = …), @StoredProcedureParameter(mode = OUT, name = "out_1", type = …)}) @Table(name = "SD_User") class User { ... } interface UserRepository extends JpaRepository<…> { @Procedure(name = "User.s1p") Integer callS1P(@Param("in_1") Integer arg);
  49. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Multiple OUT Parameters @NamedStoredProcedureQuery(name = "User.s1p", procedureName = "s1p", parameters = { @StoredProcedureParameter(mode = IN, name = "in_1", type = …), @StoredProcedureParameter(mode = OUT, name = "out_1", type = …), @StoredProcedureParameter(mode = OUT, name = "out_2", type = …)}) @Table(name = "SD_User") class User { ... } interface UserRepository extends JpaRepository<…> { @Procedure(name = "User.s1p") Map<String, Integer> callS1P(@Param("in_1") Integer arg); @Procedure Map<String, Integer> s1p(@Param("in_1") Integer arg); New in Moore
  50. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov New Features Redis Streams
  51. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Redis Streams ID <millisecondsTime>-<sequenceNumber> Key/Value 1234-0 S-12 18°C r2d2 1234-1 S-13 9°C c3p0 1235-0 S-13 18.2°C bb8 XADD XRANGE XREAD New in Moore
  52. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Redis Streams API @Autowired RedisTemplate template; StringRecord record = StreamRecords.string(…) .withStreamKey("my-stream"); template.streamOps().add(record); ID 1234-0 S-12 18°C 1234-1 S-13 9°C 1235-0 S-13 18.2°C template.streamOps().read(count(2), from(…)); XRANGE XADD New in Moore
  53. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Redis Streams - Continuous Read @Autowired RedisConnectionFactory factory; StreamListener<String, MapRecord<…> listener = (msg) -> { // … }; StreamMessageListenerContainer container = StreamMessageListenerContainer.create(factory)); container.receive(StreamOffset.fromStart("my-stream"), listener); ID 1234-0 S-12 18°C 1234-1 S-13 9°C 1235-0 S-13 18.2°C msg.getId(); msg.getStream(); msg.getValue(); New in Moore
  54. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Redis Streams StreamReceiver rcvr; rcvr.receive(StreamOffset.fromStart("my-stream")) .doOnNext(msg -> { // … }) .subscribe(); ID 1234-0 S-12 18°C 1234-1 S-13 9°C 1235-0 S-13 18.2°C New in Moore
  55. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov New Features …and more
  56. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 57 …and more JDBC uses Spring HATEOAS 1.0 Read Only Properties insert/update methods SQL generation Embeddable load options Improved SSL support Dynamic port configuration
  57. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 58 …and more ApacheTM Cassandra Id conversion Reactive GridFS JSON Schema generator Collation via annotation Fluent ChangeStream API Neo4j Spatial Types Exists projections Repository Range Queries Optimistic Locking Auditing support Derived delete Queries
  58. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ 59 …and more Non blocking connect Cluster Caching High Level Rest Client Alternative Mapper
  59. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov …ready - set - go! spring-projects/
 spring-data-examples
  60. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Image Source: NASA.gov What’s next?
  61. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Cassandra MongoDB JDBC Derived Queries Paging & Sorting Major Version Bumps shorter
 cycles Neo4j
 RX JDBC What’s next? SpringData
 R2DBC
  62. Unless otherwise indicated, these slides are © 2013-2019 Pivotal Software,

    Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/ Safe Harbor Statement The following is intended to outline the general direction of Pivotal's offerings. It is intended for information purposes only and may not be incorporated into any contract. Any information regarding pre-release of Pivotal offerings, future updates or other planned modifications is subject to ongoing evaluation by Pivotal and is subject to change. This information is provided without warranty or any kind, express or implied, and is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions regarding Pivotal's offerings. These purchasing decisions should only be based on features currently available. The development, release, and timing of any features or functionality described for Pivotal's offerings in this presentation remain at the sole discretion of Pivotal. Pivotal has no obligation to update forward looking information in this presentation.