$30 off During Our Annual Pro Sale. View Details »

What's new in Spring Data MongoDB

What's new in Spring Data MongoDB

Christoph Strobl

September 02, 2020
Tweet

More Decks by Christoph Strobl

Other Decks in Programming

Transcript

  1. September, 2020
    What’s new in Spring Data
    MongoDB
    Copyright © 2020 VMware, Inc. or its affiliates.

    View Slide

  2. Before We Start
    Staying focused is hard :)

    Documentation
    Samples
    ...


    View Slide

  3. Cover w/ Image
    Agenda
    ● Newman Release (May 2020)
    ● 2020.0 (expected end Oct 2020)
    codename Ockham
    org.springframework.data
    spring-data-releasetrain
    Neumann-SR3
    CUR
    org.springframework.data
    spring-data-bom
    2020.0.0-M2
    PRE
    org.springframework.data
    spring-data-mongodb
    3.1.0-M2
    PRE

    View Slide

  4. Spring Data MongoDB 3.0 (Neumann)
    Major version upgrade with some breaking changes
    ● Driver upgrades to 4.0
    ● Indexing Updates
    ● Updates via Aggregation pipeline
    ● Reactive GridFS changes
    ● Convenience
    org.springframework.data
    spring-data-mongodb
    3.0.3
    CUR

    View Slide

  5. org.mongodb
    mongodb-driver-reactivestreams
    1.12.0
    3.0 – Driver Upgrades
    Dependency Changes
    org.mongodb
    mongo-java-driver
    3.11.2
    2.x
    mongo-java-driver
    sync
    mongo-java-driver ...-driver-reactivestreams
    reactive

    View Slide

  6. org.mongodb
    mongodb-driver-reactivestreams
    4.0.5
    org.mongodb
    mongodb-driver-reactivestreams
    1.12.0
    3.0 – Driver Upgrades
    Dependency Changes
    org.mongodb
    mongo-java-driver
    3.11.2
    org.mongodb
    mongodb-driver-sync
    4.0.5
    org.mongodb
    mongodb-driver-core
    4.0.5
    mongo-java-driver
    mongo-java-driver ...-driver-reactivestreams
    2.x 3.0
    sync
    reactive
    mongodb-driver-core
    mongodb-driver-sync
    sync
    mongodb-driver-reactivestreams
    mongodb-driver-core
    reactive

    View Slide

  7. 3.0 – Driver Upgrades
    Configuration Changes – What it was like in 2.x
    AbstractMongoConfiguration (2.x)
    @Configuration
    class Cfg extends AbstractMongoConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    public com.mongodb.MongoClient mongoClient() {
    return new com.mongodb.MongoClient();
    }
    }

    View Slide

  8. 3.0 – Driver Upgrades
    Configuration Changes – Driver Type
    AbstractMongoClientConfiguration (3.x)
    @Configuration
    class Cfg extends AbstractMongoConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    public com.mongodb.MongoClient mongoClient() {
    return new com.mongodb.MongoClient();
    }
    }
    @Configuration
    class Cfg extends AbstractMongoClientConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    public com.mongodb.client.MongoClient mongoClient() {
    return MongoClients.create();
    }
    }
    AbstractMongoConfiguration (2.x)

    View Slide

  9. @Configuration
    class Cfg extends AbstractMongoConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    public com.mongodb.MongoClient mongoClient() {
    return new com.mongodb.MongoClient();
    }
    }
    AbstractMongoConfiguration (2.x)
    3.0 – Driver Upgrades
    Configuration Changes – Client Creation
    AbstractMongoClientConfiguration (3.x)
    @Configuration
    class Cfg extends AbstractMongoClientConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    }

    View Slide

  10. 3.0 – Driver Upgrades
    Configuration Changes – Driver Settings
    AbstractMongoClientConfiguration (3.x)
    @Configuration
    class Cfg extends AbstractMongoConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    public com.mongodb.MongoClient mongoClient() {
    MongoClientURI uri = new MongoClientURI("!!...
    return new MongoClient(uri));
    }
    }
    @Configuration
    class Cfg extends AbstractMongoClientConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    protected void configureClientSettings(Builder builder) {
    builder.applyConnectionString(new ConnectionString("...
    builder.uuidRepresentation(UuidRepresentation.STANDARD);
    }
    }
    AbstractMongoConfiguration (2.x)

    View Slide

  11. AbstractMongoClientConfiguration (3.x)
    @Configuration
    class Cfg extends AbstractMongoClientConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Override
    protected void configureClientSettings(Builder builder) {
    builder.applyConnectionString(new ConnectionString("!!..."));
    builder.uuidRepresentation(UuidRepresentation.STANDARD);
    }
    @Override
    protected boolean autoIndexCreation() {
    return true;
    }
    }
    3.0 – Driver Upgrades
    Configuration Changes - Indexing
    AbstractMongoConfiguration (2.x)
    @Document
    public class Person {
    @Id private String id;
    @Indexed(unique = true) private Integer ssn;
    private String firstName;
    @Indexed private String lastName;
    private Integer age;
    }
    {…}
    spring.data.mongodb.auto-index-creation

    View Slide

  12. 3.0 – Update via Aggregation Pipeline
    {…}
    {
    "_id" : 1,
    "student" : "Maya",
    "homework" : [ 10, 5, 10 ],
    "quiz" : [ 10, 8 ],
    "extraCredit" : 0
    }
    totalHomework : { $sum : $homework }
    totalQuiz : { $sum : $quiz }
    totalScore : {
    $add : [
    "$totalHomework",
    "$totalQuiz",
    "$extraCredit“ ]}
    Expressive, Conditional Updates
    $addFields
    $set
    $unset
    $replaceWith
    $replaceRoot
    $project

    View Slide

  13. 3.0 – Update via Aggregation Pipeline
    {…}
    {
    "_id" : 1,
    "student" : "Maya",
    "homework" : [ 10, 5, 10 ],
    "quiz" : [ 10, 8 ],
    "extraCredit" : 0
    }
    totalHomework : { $sum : $homework }
    totalQuiz : { $sum : $quiz }
    totalScore : {
    $add : [
    "$totalHomework",
    "$totalQuiz",
    "$extraCredit“ ]}
    public void calculateTotalScore() {
    AggregationUpdate update = AggregationUpdate.update()
    .set(SetOperation.builder()
    .set("totalHomework").toValueOf(valueOf("homework").sum())
    .and()
    .set("totalQuiz").toValueOf(valueOf("quiz").sum())
    .and()
    .set("totalScore").toValueOf(
    valueOf("totalHomework")
    .add("totalQuiz")
    .add("extraCredit ")));
    mongoOperations.update(Student.class)
    .apply(update)
    .all();
    }
    Expressive, Conditional Updates

    View Slide

  14. 3.0 – Reactive GridFS
    AsyncInputStream source = AsyncStreamHelper.toAsyncInputStream(resource.getInputStream());
    gridFSops.store(source, “springone", "binary/octet-stream", metadata);
    2.x

    View Slide

  15. 3.0 – Reactive GridFS
    Flux source = ...
    gridFSops.store(source, “springone", "binary/octet-stream", metadata);
    public class ReactiveGridFsResource {
    public Mono getGridFSFile() {
    !!...
    }
    }
    public Flux getContent() {
    ... // via GridFSDownloadPublisher
    }
    ReactiveGridFsResource s1p = gridFSops.getResources("s1p");
    3.0

    View Slide

  16. 3.0 – Convenience
    ...somtimes it’s the small things
    query(where("name")...)
    .withHint(
    new Document("att1", 1).append("att2", 1)
    )
    @Sharded
    public class Person {
    private @Id String id;
    private String firstname;
    }
    Shard Support
    template.query(Person.class)
    .matching(where("firstname").is("luke"))
    .one()
    Narrow API
    query(where("name")!!...).withHint("index-name")
    Index Hints (via name)
    template.query(Person.class)
    .matching(query(where("firstname").is("luke")))
    .one()

    View Slide

  17. Spring Data MongoDB 3.1 (2020.0)
    Closing gaps to the imperative implementation.
    ● Reactive SpEL in @Query annotations
    ● Reactive Auditing
    ● Repository Metrics
    ● GraalVM Native Image experience
    ● Read Only Transactions
    codename: Ockham
    The following section is intended to outline the general direction
    of VMware's offerings. It is intended for information purposes
    only and may not be incorporated into any contract. Any
    information regarding pre-release of VMware offerings, future
    updates or other planned modifications is subject to ongoing
    evaluation by VMware 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 VMware'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 VMware's offerings in this
    presentation remain at the sole discretion of VMware. VMware
    has no obligation to update forward looking information in this
    presentation.
    org.springframework.data
    spring-data-mongodb
    3.1.0-M2
    PRE

    View Slide

  18. @Query("{ 'supervisor' : ?#{ hasRole('ROLE_ADMIN') ? new Document('$regex', '*') : principal.name } }")
    Flux findAllFilteredByRole();
    3.1 – Reactive SpEL
    now truly reactive via ReactiveEvaluationContextExtension
    Flux all = repo.findAllFilteredByRole();
    all.subscribe();
    2.x

    3.1

    View Slide

  19. 3.1 – Reactive Auditing
    @CreatedBy, @CreatedDate, @LastMod...
    @Configuration
    @EnableReactiveMongoAuditing
    static class AuditingConfig extends AbstractReactiveMongoConfiguration {
    @Override
    protected String getDatabaseName() {
    return "database";
    }
    @Bean
    public ReactiveAuditorAware auditorProvider() {
    return () -> ReactiveSecurityContextHolder.getContext()
    .map(it -> ...);
    }
    }

    View Slide

  20. repo.save(fiona).subscribe();
    3.1 – Repository Metrics
    Execution Time Measurement
    PersonRepository.save(Object):
    2 ms – SUCCESS
    Flux all = repo.findAll();
    repo.save(frank).subscribe();
    all.subscribe();
    interface PersonRepository extends ReactiveCrudRepository {
    Flux findByName(String name);
    @Query("{ 'name' : { '$set' : 'Gallagher' } }")
    Flux findError();
    }
    PersonRepository.save(Object):
    2 ms - SUCCESS
    PersonRepository.findAll():
    32 ms – SUCCESS
    repo.findByName("fiona").subscribe();
    repo.findError().subscribe();
    PersonRespository.findByName(String):
    1 ms - SUCCESS
    PersonRepository.findError():
    20 ms - ERROR

    View Slide

  21. 3.1 – Repository Metrics Setup
    via Invocation Listeners
    @Bean
    public RepositoryMetricsPostProcessor repositoryMetricsPostProcessor() {
    return new RepositoryMetricsPostProcessor();
    }
    static class RepositoryMetricsPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) ...
    if (bean instanceof RepositoryFactoryBeanSupport) {
    RepositoryFactoryBeanSupport, ?, ?> repositoryFactoryBean = (...) bean;
    repositoryFactoryBean
    .addRepositoryFactoryCustomizer(repositoryFactory -> {
    repositoryFactory.addInvocationListener(System.out::println);
    });
    }
    return bean;
    }
    }

    View Slide

  22. 3.1 – GraalVM Native Image
    ...with spring-graalvm-native
    SpringDataComponentProcessor
    org.springframework.experimental
    spring-graalvm-native
    0.7.1
    SpringDataMongoDBTypeHints
    @Query
    @Aggregation
    @Document
    @Indexed
    @DBRef
    Nested Types
    Infrastructure Components ... extends CrudRepository
    Signature Types
    Methods
    Custom Implementations

    View Slide

  23. 3.1 – GraalVM Native Image
    ...with spring-graalvm-native

    View Slide

  24. © 2020 Spring. A VMware-backed project.
    Thank you
    Contact us @SpringData
    Data
    - Staying Ahead of the Curve with Spring and Cassandra 4
    - The Past Year in Spring for Apache Geode
    - A Deep Dive into Spring Application Events
    - Full Steam Ahead, R2DBC!
    - Building Flexible APIs with Spring HATEOAS
    DAY 1
    DAY 2
    GraalVM
    - Modernizing Apps for the Cloud with Spring
    - The Path Towards Spring Boot Native Applications
    - Spring Boot Revisited with KoFu and JaFu
    DAY 1
    DAY 2

    View Slide

  25. Questions?
    org.springframework.data
    spring-data-mongodb
    3.0.3
    org.springframework.experimental
    spring-graalvm-native
    0.7.1
    CUR
    org.springframework.data
    spring-data-mongodb
    3.1.0-M2
    PRE
    PRE

    View Slide