Slide 1

Slide 1 text

What’s new in Spring Data October 7–10, 2019 Austin Convention Center Moore Gordon Earle

Slide 2

Slide 2 text

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'

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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 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 Mono

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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 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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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 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);

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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 result = template.find(query, Conference.class); New in Moore

Slide 11

Slide 11 text

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 findAllByKeywordsContainsAndDateAfter(…); } @Autowired ConferenceRepo repo; //… Flux result = repo.findAllByKeywordsContainsAndDateAfter("spring", today()); New in Moore

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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 QCustomer.customer.lastname.eq("Matthews")

Slide 14

Slide 14 text

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 @Autowired Repository repo; //… Predicate predicate = QCustomer.customer.lastname.eq("Matthews"); List result = repo.findAll(predicate);

Slide 15

Slide 15 text

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 result = repo.findAll(predicate); New in Moore

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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() .matching(query(where("lastname").isEqualTo("Matthews"))) .all() List people = operations.query(Person.class) reified type parameter

Slide 18

Slide 18 text

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() .matching(query(Person::lastname isEqualTo "Matthews")) .all() where("lastname") .isEqualTo("Matthews") New in Moore

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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() .matching(query(where("lastname").isEqualTo("Matthews"))) .doOnNext { … } .subscribe() New in Moore

Slide 21

Slide 21 text

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() .matching(query(where("lastname").isEqualTo("Matthews"))) .awaitSingle() } New in Moore

Slide 22

Slide 22 text

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() .matching(query(where("lastname").isEqualTo("Matthews"))) .asFlow().toList() } New in Moore

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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 { @Override public void onBeforeSave(BeforeSaveEvent event) { event.getDocument().put(…) } } already converted (store specific)
 Person representation

Slide 29

Slide 29 text

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 beforeSave() { return (entity, document) -> { document.put(…); return entity; } } already converted (store specific)
 Person representation New in Moore

Slide 30

Slide 30 text

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 beforeConvert() { return (entity, collection) -> { return entity.withId(…); } } new Person object with and id set @Bean BeforeSaveCallback beforeSave() { return (entity, document) -> {…} } already converted (store specific)
 Person representation with changes applied New in Moore

Slide 31

Slide 31 text

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 beforeConvert() { return (entity, collection) -> { return Mono.just(entity.withId(…)); } } New in Moore

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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 aggregation = newAggregation(Order.class, 
 group(Fields.from(Fields.field("_id", "cust_id"))) .sum("amount").as("total")); AggregationResults result = ops.aggregate(aggregation, TotalByCustomer.class);

Slide 34

Slide 34 text

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/

Slide 35

Slide 35 text

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") );

Slide 36

Slide 36 text

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 { @Aggregation(" ") List 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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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 callS1P(@Param("in_1") Integer arg); @Procedure Map s1p(@Param("in_1") Integer arg); New in Moore

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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 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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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.