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

What's new in SpringData Moore

What's new in SpringData Moore

A condensed view on some of the highlights of the SpringData release train Moore.

Christoph Strobl

October 08, 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/ 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'
  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/ Image Source: NASA.gov Reactive Declarative Transactions
  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/ 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>
  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/ Declarative Transactions @EnableTransactionManagement class Config extends AbstractReactiveMongoConfiguration { @Bean ReactiveTransactionManager mgr(ReactiveMongoDatabaseFactory f) { return new ReactiveMongoTransactionManager(dbFactory); } // ... } New in Moore
  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/ 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
  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 Elasticsearch
  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/ 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);
  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/ Elasticsearch Client class Config extends AbstractReactiveElasticsearchConfiguration { @Bean @Override public ReactiveElasticsearchClient reactiveClient() { return ReactiveRestClients.create(localhost()); } } New in Moore based on WebClient
  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/ 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
  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/ Elasticsearch Repository interface ConferenceRepo extends ReactiveCrudRepository<…> { Flux<Conference> findAllByKeywordsContainsAndDateAfter(…); } @Autowired ConferenceRepo repo; //… Flux<Conference> result = repo.findAllByKeywordsContainsAndDateAfter("spring", today()); 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 Querydsl
  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/ Querydsl interface Repository extends …, QuerydslPredicateExecutor<Customer> QCustomer.customer.lastname.eq("Matthews")
  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/ Querydsl interface Repository extends …, QuerydslPredicateExecutor<Customer> @Autowired Repository repo; //… Predicate predicate = QCustomer.customer.lastname.eq("Matthews"); List<Customer> result = repo.findAll(predicate);
  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/ Querydsl interface Repository extends …, ReactiveQuerydslPredicateExecutor<…> @Autowired Repository repo; //… Predicate predicate = QCustomer.customer.lastname.eq("Matthews"); Flux<Customer> result = repo.findAll(predicate); 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/ Type-Safe Queries Kotlin
  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/ Kotlin val people = operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .all() List<Person> people = operations.query(Person.class) reified type parameter
  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/ Kotlin type-safe query DSL val people = operations.query<Person>() .matching(query(Person::lastname isEqualTo "Matthews")) .all() where("lastname") .isEqualTo("Matthews") New in Moore
  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/ Coroutines & Flow Kotlin
  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/ Kotlin operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .doOnNext { … } .subscribe() 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/ Coroutines val result = runBlocking { operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .awaitSingle() } New in Moore
  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/ Flow val result = runBlocking { operations.query<Person>() .matching(query(where("lastname").isEqualTo("Matthews"))) .asFlow().toList() } New in Moore
  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/ Image Source: NASA.gov Performance
  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/ JMH Java Microbenchmark Harness baseline native code path Derived Query Annotated Query Transactional Query Spring Data
  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/ 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
  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/ 26 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
  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/ Image Source: NASA.gov New Features Entity Callback API
  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/ 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
  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/ Modifying Entities via Callbacks @Bean BeforeSaveCallback<Person> beforeSave() { return (entity, document) -> { document.put(…); return entity; } } already converted (store specific)
 Person representation 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/ 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
  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/ Modifying Entities via Callbacks @Bean ReactiveBeforeConvertCallback<Person> beforeConvert() { return (entity, collection) -> { return Mono.just(entity.withId(…)); } } New in Moore
  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/ Image Source: NASA.gov New Features Declarative Aggregations
  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/ Aggregation Framework API @Autowired MongoOperations ops; TypedAggregation<Order> aggregation = newAggregation(Order.class, 
 group(Fields.from(Fields.field("_id", "cust_id"))) .sum("amount").as("total")); AggregationResults<TotalByCustomer> result = ops.aggregate(aggregation, TotalByCustomer.class);
  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. 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") );
  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/ 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
  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 Multiple out parameters JPA
  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/ 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
  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/ Image Source: NASA.gov New Features Redis Streams
  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/ 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
  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/ 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
  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/ 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
  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/ Image Source: NASA.gov New Features …and more
  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 …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 Scalable, Cloud-Native 
 Data Applications by Example Domain-Driven Design
 with Relational Databases 
 Using Spring Data JDBC Spring HATEOAS:
 Hypermedia APIs with Spring Wed, 2:00 pm Thu, 10:30 am Wed, 4:20 pm
  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/ 45 …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 Code Wars: How the Database 
 Affects Your Application Watch the replay
  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/ 46 …and more Non blocking connect Cluster Caching High Level Rest Client Alternative Mapper Event-Driven Java Applications
 with Redis 5.0 Streams Tue, 5:40 pm
  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/ Image Source: NASA.gov …before you go spring-projects/
 spring-data-examples
  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/ 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.