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. What’s new in Spring Data
    October 7–10, 2019
    Austin Convention Center
    Moore
    Gordon Earle

    View Slide

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

    View Slide

  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
    Reactive
    Declarative Transactions

    View Slide

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

    View Slide

  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
    @EnableTransactionManagement
    class Config extends AbstractReactiveMongoConfiguration {
    @Bean
    ReactiveTransactionManager mgr(ReactiveMongoDatabaseFactory f) {
    return new ReactiveMongoTransactionManager(dbFactory);
    }
    // ...
    }
    New in Moore

    View Slide

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

    View Slide

  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
    Elasticsearch

    View Slide

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

    View Slide

  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 Client
    class Config extends AbstractReactiveElasticsearchConfiguration {
    @Bean
    @Override
    public ReactiveElasticsearchClient reactiveClient() {
    return ReactiveRestClients.create(localhost());
    }
    }
    New in Moore
    based on WebClient

    View Slide

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

    View Slide

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

    View Slide

  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/
    Image Source: NASA.gov
    Reactive
    Querydsl

    View Slide

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

    View Slide

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

    View Slide

  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/
    Querydsl
    interface Repository extends …, ReactiveQuerydslPredicateExecutor<…>
    @Autowired
    Repository repo;
    //…
    Predicate predicate = QCustomer.customer.lastname.eq("Matthews");
    Flux result = repo.findAll(predicate);
    New in Moore

    View Slide

  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/
    Type-Safe Queries
    Kotlin

    View Slide

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

    View Slide

  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/
    Kotlin type-safe query DSL
    val people = operations.query()
    .matching(query(Person::lastname isEqualTo "Matthews"))
    .all()
    where("lastname")
    .isEqualTo("Matthews")
    New in Moore

    View Slide

  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/
    Coroutines & Flow
    Kotlin

    View Slide

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

    View Slide

  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/
    Coroutines
    val result = runBlocking {
    operations.query()
    .matching(query(where("lastname").isEqualTo("Matthews")))
    .awaitSingle()
    }
    New in Moore

    View Slide

  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/
    Flow
    val result = runBlocking {
    operations.query()
    .matching(query(where("lastname").isEqualTo("Matthews")))
    .asFlow().toList()
    }
    New in Moore

    View Slide

  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/
    Image Source: NASA.gov
    Performance

    View Slide

  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
    Java Microbenchmark Harness
    baseline
    native code path
    Derived Query
    Annotated Query
    Transactional Query
    Spring Data

    View Slide

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

    View Slide

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

    View Slide

  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/
    Image Source: NASA.gov
    New Features
    Entity Callback API

    View Slide

  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 Events
    @Component
    class MongoListener extends AbstractMongoEventListener {
    @Override
    public void onBeforeSave(BeforeSaveEvent event) {
    event.getDocument().put(…)
    }
    }
    already converted (store specific)

    Person representation

    View Slide

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

    Person representation
    New in Moore

    View Slide

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

    View Slide

  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/
    Modifying Entities via Callbacks
    @Bean
    ReactiveBeforeConvertCallback beforeConvert() {
    return (entity, collection) -> {
    return Mono.just(entity.withId(…));
    }
    }
    New in Moore

    View Slide

  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/
    Image Source: NASA.gov
    New Features
    Declarative Aggregations

    View Slide

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

    View Slide

  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/

    View Slide

  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/
    MongoDB Aggregations
    {$group:{_id:'$cust_id',total:{$sum:'$amount'}}}
    newAggregation(Order.class, group(

    Fields.from(Fields.field("_id", "cust_id")))
    .sum("amount").as("total")
    );

    View Slide

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

    View Slide

  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/
    Image Source: NASA.gov
    New Features
    Multiple out parameters
    JPA

    View Slide

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

    View Slide

  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/
    Image Source: NASA.gov
    New Features
    Redis Streams

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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/
    Image Source: NASA.gov
    New Features
    …and more

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    …before you go
    spring-projects/

    spring-data-examples

    View Slide

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

    View Slide