What's new in recent Spring Data release train Moore and what the team has planned for the next one (aka Neumann).
Spring Data Moore…and BeyondGordon Earle
View Slide
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 traitsof the underlying data store.
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 {Optional findById(String id);List findByName(String name);}Spring Data … what?JDBC ApacheTM CassandraJPA
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.gov375 Days700+ Issues16 Modules
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.gov16 Modules375 Days700+ IssuesKotlinPerformanceReactive
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.gov16 Modules375 Days700+ IssuesKotlinPerformanceReactiveNew FeaturesCoroutines & FlowDeclarative Reactive Transactions60% faster finder methods* * for eg. JPA single attribute finder like 'findByTitle'
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.govReactive
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.govReactiveDeclarative Transactions
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/Transactionspublic 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();}FluxMono
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@EnableTransactionManagementclass Config extends AbstractReactiveMongoConfiguration {@BeanReactiveTransactionManager mgr(ReactiveMongoDatabaseFactory f) {return new ReactiveMongoTransactionManager(dbFactory);}// ...}New in Moore
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@Transactionalpublic 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
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.govReactiveElasticsearch
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<>() {@Overridepublic void onResponse(SearchResponse searchResponse) {sink.success(searchResponse);}@Overridepublic void onFailure(Exception e) {sink.error(e);
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 Clientclass Config extends AbstractReactiveElasticsearchConfiguration {@Bean@Overridepublic ReactiveElasticsearchClient reactiveClient() {return ReactiveRestClients.create(localhost());}}based on WebClientNew in Moore
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@AutowiredReactiveElasticsearchTemplate 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
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 Repositoryinterface ConferenceRepo extends ReactiveCrudRepository<…> {Flux findAllByKeywordsContainsAndDateAfter(…);}@AutowiredConferenceRepo repo;//…Flux result =repo.findAllByKeywordsContainsAndDateAfter("spring", today());New in Moore
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.govReactiveQuerydsl
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/Querydslinterface Repository extends …, QuerydslPredicateExecutorQCustomer.customer.lastname.eq("Matthews")
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/Querydslinterface Repository extends …, QuerydslPredicateExecutor@AutowiredRepository repo;//…Predicate predicate = QCustomer.customer.lastname.eq("Matthews");List result = repo.findAll(predicate);
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/Querydslinterface Repository extends …, ReactiveQuerydslPredicateExecutor<…>@AutowiredRepository repo;//…Predicate predicate = QCustomer.customer.lastname.eq("Matthews");Flux result = repo.findAll(predicate);New in Moore
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
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 QueriesKotlin
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/Kotlinval people = operations.query().matching(query(where("lastname").isEqualTo("Matthews"))).all()Kotlin Extension to avoid `is` (…
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/Kotlinval people = operations.query().matching(query(where("lastname").isEqualTo("Matthews"))).all()List people = operations.query(Person.class)reified type parameter
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 DSLval people = operations.query().matching(query(Person::lastname isEqualTo "Matthews")).all()where("lastname").isEqualTo("Matthews")New in MooreNew in Moore
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 & FlowKotlin
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/Kotlinoperations.query().matching(query(where("lastname").isEqualTo("Matthews"))).doOnNext { … }.subscribe()New in Moore
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/Coroutinesval result = runBlocking {operations.query().matching(query(where("lastname").isEqualTo("Matthews"))).awaitSingle()}New in Moore
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/Flowval result = runBlocking {operations.query().matching(query(where("lastname").isEqualTo("Matthews"))).asFlow().toList()}New in Moore
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.govPerformance
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/JMHJava Microbenchmark Harnessbaselinenative code pathDerived QueryAnnotated QueryTransactional QuerySpring Data
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@Benchmarkpublic 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());}@Benchmarkpublic void repositoryFindByTitle(Blackhole sink) {sink.consume(repository.findDerivedByTitle("title0"));}native code pathSpring Data
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/ 33Ops/sec**spring-data-jpa in memory H2 SQL Mac Book Pro 3.2 GHzRC1 RC2findAll 52.213 61.244findByTitle 74.192 123.040repositoryByTitle 70.344 120.333repositoryByTitleDeclared 65.236 111.760
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/ 34RC1 RC2findAll 52.213 61.244findByTitle 74.192 123.040repositoryByTitle 70.344 120.333repositoryByTitleDeclared 65.236 111.760Ops/sec**spring-data-jpa in memory H2 SQL Mac Book Pro 3.2 GHz
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/ 35RC1 RC2findAll 52.213 61.244findByTitle 74.192 123.040repositoryByTitle 70.344 120.333repositoryByTitleDeclared 65.236 111.760Ops/sec**spring-data-jpa in memory H2 SQL Mac Book Pro 3.2 GHzClean Room Scenario!Almost each and every performancebenchmark avoids any kind ofoverhead whatsoever.
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.govNew Features
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.govNew FeaturesEntity Callback API
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@Componentclass MongoListener extends AbstractMongoEventListener {@Overridepublic void onBeforeSave(BeforeSaveEvent event) {event.getDocument().put(…)}}already converted (store specific) Person representation
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@BeanBeforeSaveCallback beforeSave() {return (entity, document) -> {document.put(…);return entity;}}already converted (store specific) Person representationNew in Moore
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@BeanBeforeConvertCallback beforeConvert() {return (entity, collection) -> {return entity.withId(…);}}new Person object with and id set@BeanBeforeSaveCallback beforeSave() {return (entity, document) -> {…}} already converted (store specific) Person representation with changes appliedNew in Moore
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@BeanReactiveBeforeConvertCallback beforeConvert() {return (entity, collection) -> {return Mono.just(entity.withId(…));}}New in Moore
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.govNew FeaturesDeclarative Aggregations
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"));
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/
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"));
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
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
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.govNew FeaturesMultiple out parametersJPA
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);
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);@ProcedureMap s1p(@Param("in_1") Integer arg);New in Moore
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.govNew FeaturesRedis Streams
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 StreamsID- Key/Value1234-0 S-12 18°C r2d21234-1 S-13 9°C c3p01235-0 S-13 18.2°C bb8XADDXRANGEXREADNew in Moore
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@AutowiredRedisTemplate template;StringRecord record = StreamRecords.string(…).withStreamKey("my-stream");template.streamOps().add(record);ID1234-0 S-12 18°C1234-1 S-13 9°C1235-0 S-13 18.2°Ctemplate.streamOps().read(count(2), from(…));XRANGEXADDNew in Moore
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@AutowiredRedisConnectionFactory factory;StreamListener listener =(msg) -> {// …};StreamMessageListenerContainer container =StreamMessageListenerContainer.create(factory));container.receive(StreamOffset.fromStart("my-stream"), listener);ID1234-0 S-12 18°C1234-1 S-13 9°C1235-0 S-13 18.2°Cmsg.getId();msg.getStream();msg.getValue();New in Moore
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 StreamsStreamReceiver rcvr;rcvr.receive(StreamOffset.fromStart("my-stream")).doOnNext(msg -> {// …}).subscribe();ID1234-0 S-12 18°C1234-1 S-13 9°C1235-0 S-13 18.2°CNew in Moore
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.govNew Features…and more
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 moreJDBCuses Spring HATEOAS 1.0Read Only Propertiesinsert/update methodsSQL generationEmbeddable load optionsImproved SSL supportDynamic port configuration
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 moreApacheTM CassandraId conversionReactive GridFSJSON Schema generatorCollation via annotationFluent ChangeStream APINeo4j Spatial TypesExists projectionsRepository Range QueriesOptimistic LockingAuditing supportDerived delete Queries
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 moreNon blocking connectCluster CachingHigh Level Rest ClientAlternative Mapper
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
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.govWhat’s next?
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/CassandraMongoDBJDBCDerived QueriesPaging & SortingMajorVersionBumpsshorter cyclesNeo4j RXJDBCWhat’s next?SpringData R2DBC
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 StatementThe following is intended to outline the general direction of Pivotal's offerings. It is intended for information purposes only andmay not be incorporated into any contract. Any information regarding pre-release of Pivotal offerings, future updates or otherplanned modifications is subject to ongoing evaluation by Pivotal and is subject to change. This information is provided withoutwarranty or any kind, express or implied, and is not a commitment to deliver any material, code, or functionality, and should notbe relied upon in making purchasing decisions regarding Pivotal's offerings. These purchasing decisions should only be basedon features currently available. The development, release, and timing of any features or functionality described for Pivotal'sofferings in this presentation remain at the sole discretion of Pivotal. Pivotal has no obligation to update forward lookinginformation in this presentation.