Successfully reported this slideshow.
Your SlideShare is downloading. ×

Modern Persistence with Spring Data 3

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 43 Ad

Modern Persistence with Spring Data 3

Download to read offline

In this session, we have a comprehensive look at what’s new and noteworthy in Spring Data 3.0. We cover new ways of composing repository interfaces as well as the Ahead of Time (AoT) infrastructure, which is based on Framework 6. We also share our experience of creating Spring-native applications that use all the new features of your favorite datastore from inside a GraalVM native image.

In this session, we have a comprehensive look at what’s new and noteworthy in Spring Data 3.0. We cover new ways of composing repository interfaces as well as the Ahead of Time (AoT) infrastructure, which is based on Framework 6. We also share our experience of creating Spring-native applications that use all the new features of your favorite datastore from inside a GraalVM native image.

Advertisement
Advertisement

More Related Content

More from VMware Tanzu (20)

Recently uploaded (20)

Advertisement

Modern Persistence with Spring Data 3

  1. 1. │©2022 VMware, Inc. Modern Persistence With Spring Data 3
  2. 2. People Standing on Platform of a Subway Station - Niklas Jeromin - https://www.pexels.com/
  3. 3. Baseline Java 17 Framework 6 Jakarta EE 9
  4. 4. Baseline Framework 6 /* * Extend Future with the capability to accept completion callbacks. * @deprecated as of 6.0, in favor of CompletableFuture */ @Deprecated(since = "6.0") public interface ListenableFuture<T> extends Future<T> { ... } future.addCallback( it -> { ... }, exception -> { ... } ); future.whenComplete( (it, exception) -> { ... } );
  5. 5. Minimum Baseline Java 17 Framework 6 Jakarta EE 9 /* * Extend Future with the capability to accept completion callbacks. * @deprecated as of 6.0, in favor of CompletableFuture */ @Deprecated(since = "6.0") public interface ListenableFuture<T> extends Future<T> { ... } future.addCallback(it -> { ... }, exception -> { ... }); future.whenComplete((it, exception) -> { ... });
  6. 6. RxJava1 & RxJava2 support discontinued import io.reactivex.Maybe; interface RxPersonRepository extends RxJava2CrudRepository { Maybe<Person> findPersonById(Long id); } import io.reactivex.rxjava3.core.Maybe; interface RxPersonRepository extends RxJava3CrudRepository { Maybe<Person> findPersonById(Long id); }
  7. 7. import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; Baseline Jakarte EE 9 -Drewrite.activeRecipes=org.openrewrite.java.migrate.JavaxMigrationToJakarta $> java -jar spring-boot-migrator.jar jee-project:> apply initialize-spring-boot-migration SBM $> find * -name '*.java' | xargs perl -pi -e "s/javax.persistence./jakarta.persistence./g" Bash
  8. 8. OSS Support extended
  9. 9. In October 2022, the Apache Geode project failed to secure at least three voting members on the PMC required to maintain and manage the Apache Geode Project, after which it was moved to the foundations Attic. Spring Data for Apache Geode discontinued
  10. 10. Spring Data for Apache Geode
  11. 11. digital mixer, public domain cc0 - https://www.rawpixel.com/image/5920690
  12. 12. jar native - image
  13. 13. @Bean public MongoManagedTypes managedTypes() { return MongoManagedTypes.from(Customer.class, Order.class); } From Spring Native to Boot 3 Thursday, Jan 26 ‘23
  14. 14. Micrometer integtration Apache Cassandra MongoDB Redis Traces Metrics Logs Observability of Your Application Wednesday, Jan 25 ‘23
  15. 15. management.metrics.mongo.command.enabled=false Observability Data MongoDB < 3.1
  16. 16. @SpringBootApplication public class SpringDataMongodbObservabilityApplication { @Bean CommandLineRunner initDatabase(EmployeeRepository repository, ObservationRegistry registry) { // ... } @Bean MongoClientSettingsBuilderCustomizer mongoContextProvider(ObservationRegistry registry) { return (clientSettingsBuilder) -> clientSettingsBuilder.contextProvider(ContextProviderFactory.create(registry)) .addCommandListener(new MongoObservationCommandListener(registry)); } } Observability Data MongoDB
  17. 17. @SpringBootApplication public class SpringDataMongodbObservabilityApplication { @Bean CommandLineRunner initDatabase(EmployeeRepository repository, ObservationRegistry registry) { return args -> { Observation.createNotStarted("init-database", registry).observe(() -> { repository.save(new Employee("Frodo", "ring bearer")); repository.save(new Employee("Bilbo", "burglar")); }); }; } @Bean MongoClientSettingsBuilderCustomizer mongoContextProvider(ObservationRegistry registry) { return (clientSettingsBuilder) -> clientSettingsBuilder.contextProvider(ContextProviderFactory.create(registry)) .addCommandListener(new MongoObservationCommandListener(registry)); } } Observability Data MongoDB
  18. 18. Data JPA
  19. 19. @Query(value = "select u.* from User u", queryRewriter = TenantQRW.class) List<User> findUsers(Pageable pageable); static class TenantQRW implements QueryRewriter { @Override public String rewrite(String query, Sort sort) { return query + " WHERE u.tenantId = " + context.getTenantId(); } } Data JPA Query Rewriter
  20. 20. Data JDBC
  21. 21. @Query("SELECT * FROM person WHERE username = :#{ principal?.username }") Person findActiveUser(); Data JDBC SpEL Expressions
  22. 22. @EnableJdbcRepositories static class AppConfiguration { // ... @Bean BeforeConvertCallback<Person> idGenerator() { return p -> p.withId(UUID.randomUUID()); } } Data JDBC Lifecycle Events & Callbacks
  23. 23. Data JDBC Operation Batching A B
  24. 24. Data JDBC Operation Batching A B
  25. 25. Data MongoDB
  26. 26. template.createView("firstYears", Student.class, match(where("year").is(1))); Data MongoDB Views
  27. 27. Person existing = template.update(Person.class) .matching(where("firstname").is("Harry")) .apply(new Update().inc("age", 1)) .findAndModifyValue(); @Update("{ '$inc' : { 'age' : ?1 } }") Person findAndIncrementAgeByFirstname(String firstname, int increment); Data MongoDB findAndModify
  28. 28. Data MongoDB Aggregations
  29. 29. Aggregation.stage(search(exists(fieldPath("age")))); Data MongoDB Aggregations spring-data mongodb-driver
  30. 30. Data Redis
  31. 31. public class User { @JsonView(Basic.class) private int id; @JsonView(Basic.class) private String name; @JsonView(Detailed.class) private String email; } Data Redis Object Mapping new GenericJackson2JsonRedisSerializer(objectMapper, JacksonObjectReader.create(), (mapper, source) -> mapper.writerWithView(Basic.class).writeValueAsBytes(source) );
  32. 32. What’s next?
  33. 33. Single Select queries A B C ⋈ naïve join
  34. 34. Single Select queries A B C ⋈ analytic join
  35. 35. public class Person { String id; String name; @EncryptedField(algorithm = SHA_512_Deterministic) String ssn; @EncryptedField(algorithm = SHA_512_Random, altKeyName = "secretKey") String wallet; @EncryptedField(algorithm = SHA_512_Random, altKeyName = "/name") Address address; } Encryption client side
  36. 36. public class Person { String id; String name; @EncryptedField(algorithm = SHA_512_Deterministic) String ssn; @EncryptedField(algorithm = SHA_512_Random, altKeyName = "secretKey") String wallet; @EncryptedField(algorithm = SHA_512_Random, altKeyName = "/name") Address address; } Encryption client side { "_id": "ff3-4567-ee", "name": "chris", "ssn": { "$binary": { "base64": "AVpT0rwbK0P "subType": "06" } }, "wallet": { "$binary": { "base64": "AlpT0rwbK0P "subType": "06" } }, "address": { "$binary": { "base64": "+T3C+n4HOBF "subType": "06" } }, "_class": ”example.Person" }

×