{{announcement.body}}
{{announcement.title}}

What's New With Jakarta NoSQL? (Part 1): Intro to Document With MongoDB

DZone 's Guide to

What's New With Jakarta NoSQL? (Part 1): Intro to Document With MongoDB

This post will talk about the newest milestone version of this new specification and more.

· Database Zone ·
Free Resource

Stack of documents and books

Jakarta EE picks up where Java EE 8 left off, but the roadmap going forward will be focused on modern innovations like microservices, modularity, and NoSQL databases. This post will talk about the newest milestone version of this new specification and the subsequent actions to make the Jakarta EE community even greater in the cloud.


Why Jakarta NoSQL?

Vendor lock-in is one of the things any Java developer needs to consider when choosing NoSQL databases. If there’s a need for a switch, other considerations include time spent on the change, the learning curve of a new API to use with this database, the code that will be lost, the persistence layer that needs to be replaced. Jakarta NoSQL avoids most of these issues through Communication APIs. Jakarta NoSQL also has template classes that apply the design pattern ‘template method’ to database operations. And the Repository interface allows Java developers to create and extend interfaces, with implementation automatically provided by Jakarta NoSQL — support method queries built by developers will automatically be implemented for them.

You might also like: Jakarta EE: Generation IV — A New Hope

To make it clear, let’s create some sample code. The picture below shows four different databases:

  • ArangoDB
  • MongoDB
  • Couchbase
  • OrientDB


What do Those Databases Have in Common?

Yup, they’re all document NoSQL databases, and they’re trying to create a document, a tuple with a name, and the information itself. They’re all doing the exact same thing with the same behavior goal, however, with a different class, method name, and so on. So, if you want to move your code from one database to another, you need to learn a new API and update the whole database code to the database API code target.

Through the communication specification, we can easily change between databases just by using the driver databases that look like JDBC drivers. So, you can be more comfortable learning a new NoSQL database from the software architecture perspective; we can easily and quickly jump to another NoSQL.

Show me the code API

To demonstrate how the Jakarta NoSQL works, let’s create a small REST API; that API will run in cloud with Platform.sh. The API will handle the heroes, and all the information will be stored into MongoDB. As a first step, we need to set the dependencies Jakarta NoSQL needs:

  • Jakarta Context Dependency Injection 2.0. Jakarta Contexts Dependency Injection specifies a means for obtaining objects that maximize reusability, testability, and maintainability—compared to traditional approaches such as constructors, factories, and service locators. Think of it as a glue for the entire Jakarta EE world.
  • Jakarta JSON Binding. Defines a binding framework for converting Java objects to and from JSON documents.
  • Jakarta Bean Validation 2.0 (optional). Jakarta Bean Validation defines a metadata model and API for JavaBean and method validation.
  • Eclipse MicroProfile Configuration (optional). Eclipse MicroProfile Config is a solution to externalize configuration from Java applications.
XML
x
69
1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
    <modelVersion>4.0.0</modelVersion>
4
    <groupId>org.soujava</groupId>
5
    <artifactId>heroes</artifactId>
6
    <version>1.0-SNAPSHOT</version>
7
    <packaging>war</packaging>
8
    <name>heroes-demo</name>
9
    <url>https://soujava.org.br/</url>
10
    <properties>
11
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
12
        <maven.compiler.source>1.8</maven.compiler.source>
13
        <maven.compiler.target>1.8</maven.compiler.target>
14
        <failOnMissingWebXml>false</failOnMissingWebXml>
15
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16
        <version.microprofile>2.2</version.microprofile>
17
        <version.payara.micro>5.193.1</version.payara.micro>
18
        <payara.version>1.0.5</payara.version>
19
        <platform.sh.version>2.2.3</platform.sh.version>
20
        <jakarta.nosql.version>1.0.0-b1</jakarta.nosql.version>
21
    </properties>
22
 
          
23
    <dependencies>
24
        <dependency>
25
            <groupId>jakarta.platform</groupId>
26
            <artifactId>jakarta.jakartaee-web-api</artifactId>
27
            <version>8.0.0</version>
28
        </dependency>
29
        <dependency>
30
            <groupId>org.eclipse.microprofile.config</groupId>
31
            <artifactId>microprofile-config-api</artifactId>
32
            <version>1.3</version>
33
            <scope>provided</scope>
34
        </dependency>
35
        <dependency>
36
            <groupId>org.eclipse.jnosql.artemis</groupId>
37
            <artifactId>artemis-document</artifactId>
38
            <version>${jakarta.nosql.version}</version>
39
        </dependency>
40
        <dependency>
41
            <groupId>org.eclipse.jnosql.diana</groupId>
42
            <artifactId>mongodb-driver</artifactId>
43
            <version>${jakarta.nosql.version}</version>
44
        </dependency>
45
    </dependencies>
46
    <build>
47
        <finalName>heros</finalName>
48
        <plugins>
49
            <plugin>
50
                <groupId>org.apache.maven.plugins</groupId>
51
                <artifactId>maven-war-plugin</artifactId>
52
                <version>3.2.2</version>
53
                <configuration>
54
                    <failOnMissingWebXml>false</failOnMissingWebXml>
55
                    <packagingExcludes>pom.xml</packagingExcludes>
56
                </configuration>
57
            </plugin>
58
            <plugin>
59
                <groupId>fish.payara.maven.plugins</groupId>
60
                <artifactId>payara-micro-maven-plugin</artifactId>
61
                <version>${payara.version}</version>
62
                <configuration>
63
                    <payaraVersion>${version.payara.micro}</payaraVersion>
64
                    <autoDeployEmptyContextRoot>true</autoDeployEmptyContextRoot>
65
                </configuration>
66
            </plugin>
67
        </plugins>
68
    </build>
69
</project>


One amazing aspect of using Platform.sh is that we don’t need to worry about the infrastructure installation that includes the MongoDB server itself; it will create several containers that include the application and the database. We’ll talk more about Platform.sh and its relationship with cloud-native soon.

The first step is to create the Hero entity, in the annotations package now as jakarta.nosql.mapping.

Java
xxxxxxxxxx
1
65
 
1
import jakarta.nosql.mapping.Column;
2
import jakarta.nosql.mapping.Entity;
3
import jakarta.nosql.mapping.Id;
4
 
          
5
import javax.json.bind.annotation.JsonbVisibility;
6
import java.io.Serializable;
7
import java.util.Objects;
8
import java.util.Set;
9
 
          
10
@Entity
11
@JsonbVisibility(FieldPropertyVisibilityStrategy.class)
12
public class Hero implements Serializable {
13
 
          
14
    @Id
15
    private String name;
16
 
          
17
    @Column
18
    private Integer age;
19
 
          
20
    @Column
21
    private Set<String> powers;
22
 
          
23
    @Override
24
    public boolean equals(Object o) {
25
        if (this == o) {
26
            return true;
27
        }
28
        if (!(o instanceof Hero)) {
29
            return false;
30
        }
31
        Hero hero = (Hero) o;
32
        return Objects.equals(name, hero.name);
33
    }
34
 
          
35
    @Override
36
    public int hashCode() {
37
        return Objects.hashCode(name);
38
    }
39
 
          
40
    @Override
41
    public String toString() {
42
        return "Hero{" +
43
                "name='" + name + '\'' +
44
                ", age=" + age +
45
                ", powers=" + powers +
46
                '}';
47
    }
48
}
49
 
          
50
import javax.json.bind.config.PropertyVisibilityStrategy;
51
import java.lang.reflect.Field;
52
import java.lang.reflect.Method;
53
 
          
54
public class FieldPropertyVisibilityStrategy implements PropertyVisibilityStrategy {
55
 
          
56
    @Override
57
    public boolean isVisible(Field field) {
58
        return true;
59
    }
60
 
          
61
    @Override
62
    public boolean isVisible(Method method) {
63
        return true;
64
    }
65
}


The next step is to create a connection to the NoSQL database, so we’ll create a DocumentCollectionManager instance. Think of EntityManager as a Document database. We know that hard-coded information isn’t safe nor is it a t good practice. That’s why the twelve-factor mentions it in the third section. Further, the application doesn’t need to know where this information comes from. To follow the good practices of the twelve-factor and to support the cloud-native principle, Jakarta NoSQL has support for the Eclipse MicroProfile Configuration.


Java
xxxxxxxxxx
1
24
 
1
import jakarta.nosql.document.DocumentCollectionManager;
2
import org.eclipse.microprofile.config.inject.ConfigProperty;
3
 
          
4
import javax.enterprise.context.ApplicationScoped;
5
import javax.enterprise.inject.Disposes;
6
import javax.enterprise.inject.Produces;
7
import javax.inject.Inject;
8
 
          
9
@ApplicationScoped
10
class DocumentManagerProducer {
11
 
          
12
    @Inject
13
    @ConfigProperty(name = "document")
14
    private DocumentCollectionManager manager;
15
 
          
16
    @Produces
17
    public DocumentCollectionManager getManager() {
18
        return manager;
19
    }
20
 
          
21
    public void destroy(@Disposes DocumentCollectionManager manager) {
22
        manager.close();
23
    }
24
}


Once this is done, we create a connection class that makes a DocumentCollectionManager instance available to CDI, thanks to the method annotated with Produces.

The database configuration is ready to run locally. For this application beyond the CRUD, let’s create three more queries:

  • Find all Heroes
  • Find Heroes older than a certain age
  • Find heroes younger than a certain age
  • Find Heroes by the name, the id
  • Find Heroes by the power

We have several ways to create this query into Jakarta NoSQL. Let’s introduce the first way with DocumentTemplate. The template classes execute operations into NoSQL database in the Mapper layer, so there’s a template class for each NoSQL type that Jakarta NoSQL supports: DocumentTemplate for document, KeyValueTemplate for key-value database, and so on.

Even with Document Template, we have two paths to consult information into NoSQL databases. The first one is programmatically. The API has a fluent way to create a DocumentQuery instance.


Java
x
 
1
import jakarta.nosql.document.DocumentDeleteQuery;
2
import jakarta.nosql.document.DocumentQuery;
3
import jakarta.nosql.mapping.document.DocumentTemplate;
4
import com.google.common.collect.Sets;
5
 
          
6
import javax.enterprise.context.ApplicationScoped;
7
import javax.inject.Inject;
8
import java.util.Optional;
9
import java.util.stream.Collectors;
10
import java.util.stream.Stream;
11
 
          
12
import static jakarta.nosql.document.DocumentDeleteQuery.delete;
13
import static jakarta.nosql.document.DocumentQuery.select;
14
import static java.util.Arrays.asList;
15
 
          
16
@ApplicationScoped
17
public class FluentAPIService {
18
 
          
19
    @Inject
20
    private DocumentTemplate template;
21
 
          
22
    public void execute() {
23
 
          
24
        Hero iron = new Hero("Iron man", 32, Sets.newHashSet("Rich"));
25
        Hero thor = new Hero("Thor", 5000, Sets.newHashSet("Force", "Thunder", "Strength"));
26
        Hero captainAmerica = new Hero("Captain America", 80, Sets.newHashSet("agility",
27
                "Strength", "speed", "endurance"));
28
        Hero spider = new Hero("Spider", 18, Sets.newHashSet("Spider", "Strength"));
29
 
          
30
        DocumentDeleteQuery deleteQuery = delete().from("Hero")
31
                .where("_id").in(Stream.of(iron, thor, captainAmerica, spider)
32
                        .map(Hero::getName).collect(Collectors.toList())).build();
33
        template.delete(deleteQuery);
34
 
          
35
 
          
36
        template.insert(asList(iron, thor, captainAmerica, spider));
37
        //find by id
38
        Optional<Hero> hero = template.find(Hero.class, iron.getName());
39
        System.out.println(hero);
40
 
          
41
        //query younger
42
        DocumentQuery youngQuery = select().from("Hero")
43
                .where("age").lt(20).build();
44
 
          
45
        //query seniors
46
        DocumentQuery seniorQuery = select().from("Hero")
47
                .where("age").gt(20).build();
48
 
          
49
           //query powers
50
        DocumentQuery queryPower = select().from("Hero")
51
                .where("powers").in(Collections.singletonList("Strength"))
52
                .build();
53
 
          
54
        Stream<Hero> youngStream = template.select(youngQuery);
55
 
          
56
        Stream<Hero> seniorStream = template.select(seniorQuery);
57
 
          
58
        Stream<Hero> strengthStream = template.select(queryPower);
59
 
          
60
        String yongHeroes = youngStream.map(Hero::getName).collect(Collectors.joining(","));
61
        String seniorsHeroes = seniorStream.map(Hero::getName).collect(Collectors.joining(","));
62
        String strengthHeroes = strengthStream.map(Hero::getName).collect(Collectors.joining(","));
63
 
          
64
        System.out.println("Young result: " + yongHeroes);
65
        System.out.println("Seniors result: " + seniorsHeroes);
66
        System.out.println("Strength result: " + strengthHeroes);
67
    }
68
}


To talk about the ‘find all heroes’ query, we’ll create a specific class because when we talk about returning all information in a database, we need to avoid an impact on performance. Given a database might have more than one million information points, it doesn’t make sense to bring all this information at the same time (in most cases).


Java
xxxxxxxxxx
1
57
 
1
import jakarta.nosql.document.DocumentDeleteQuery;
2
import jakarta.nosql.document.DocumentQuery;
3
import jakarta.nosql.mapping.document.DocumentTemplate;
4
import com.google.common.collect.Sets;
5
 
          
6
import javax.enterprise.context.ApplicationScoped;
7
import javax.inject.Inject;
8
import java.util.Arrays;
9
import java.util.Optional;
10
import java.util.stream.Collectors;
11
import java.util.stream.Stream;
12
 
          
13
import static jakarta.nosql.document.DocumentDeleteQuery.delete;
14
import static jakarta.nosql.document.DocumentQuery.select;
15
import static java.util.Arrays.asList;
16
 
          
17
@ApplicationScoped
18
public class FluentAPIFindAllService {
19
 
          
20
    @Inject
21
    private DocumentTemplate template;
22
 
          
23
    public void execute() {
24
 
          
25
        Hero iron = new Hero("Iron man", 32, Sets.newHashSet("Rich"));
26
        Hero thor = new Hero("Thor", 5000, Sets.newHashSet("Force", "Thunder"));
27
        Hero captainAmerica = new Hero("Captain America", 80, Sets.newHashSet("agility",
28
                "strength", "speed", "endurance"));
29
        Hero spider = new Hero("Spider", 18, Sets.newHashSet("Spider"));
30
 
          
31
        DocumentDeleteQuery deleteQuery = delete().from("Hero")
32
                .where("_id").in(Stream.of(iron, thor, captainAmerica, spider)
33
                        .map(Hero::getName).collect(Collectors.toList())).build();
34
        template.delete(deleteQuery);
35
        template.insert(Arrays.asList(iron, thor, captainAmerica, spider));
36
 
          
37
        DocumentQuery query = select()
38
                .from("Hero")
39
                .build();
40
 
          
41
        Stream<Hero> heroes = template.select(query);
42
        Stream<Hero> peek = heroes.peek(System.out::println);
43
        System.out.println("The peek is not happen yet");
44
        System.out.println("The Heroes names: " + peek.map(Hero::getName)
45
                .collect(Collectors.joining(", ")));
46
 
          
47
        DocumentQuery querySkipLimit = select()
48
                .from("Hero")
49
                .skip(0)
50
                .limit(1)
51
                .build();
52
 
          
53
        Stream<Hero> heroesSkip = template.select(querySkipLimit);
54
        System.out.println("The Heroes names: " + heroesSkip.map(Hero::getName)
55
                .collect(Collectors.joining(", ")));
56
    }
57
}


Also, the API has the pagination feature that easily accommodates pagination and functions with large sets of data.


Java
xxxxxxxxxx
1
58
 
1
import jakarta.nosql.document.DocumentDeleteQuery;
2
import jakarta.nosql.document.DocumentQuery;
3
import jakarta.nosql.mapping.Page;
4
import jakarta.nosql.mapping.Pagination;
5
import jakarta.nosql.mapping.document.DocumentQueryPagination;
6
import jakarta.nosql.mapping.document.DocumentTemplate;
7
import com.google.common.collect.Sets;
8
 
          
9
import javax.enterprise.context.ApplicationScoped;
10
import javax.inject.Inject;
11
import java.util.Arrays;
12
import java.util.stream.Collectors;
13
import java.util.stream.Stream;
14
 
          
15
import static jakarta.nosql.document.DocumentDeleteQuery.delete;
16
import static jakarta.nosql.document.DocumentQuery.select;
17
 
          
18
@ApplicationScoped
19
public class FluentAPIPaginationService {
20
 
          
21
    @Inject
22
    private DocumentTemplate template;
23
 
          
24
    public void execute() {
25
 
          
26
        Hero iron = new Hero("Iron man", 32, Sets.newHashSet("Rich"));
27
        Hero thor = new Hero("Thor", 5000, Sets.newHashSet("Force", "Thunder"));
28
        Hero captainAmerica = new Hero("Captain America", 80, Sets.newHashSet("agility",
29
                "strength", "speed", "endurance"));
30
        Hero spider = new Hero("Spider", 18, Sets.newHashSet("Spider"));
31
 
          
32
        DocumentDeleteQuery deleteQuery = delete().from("Hero")
33
                .where("_id").in(Stream.of(iron, thor, captainAmerica, spider)
34
                        .map(Hero::getName).collect(Collectors.toList())).build();
35
        template.delete(deleteQuery);
36
        template.insert(Arrays.asList(iron, thor, captainAmerica, spider));
37
 
          
38
        DocumentQuery query = select()
39
                .from("Hero")
40
                .orderBy("_id")
41
                .asc()
42
                .build();
43
 
          
44
        DocumentQueryPagination pagination =
45
                DocumentQueryPagination.of(query, Pagination.page(1).size(1));
46
 
          
47
        Page<Hero> page1 = template.select(pagination);
48
 
          
49
        System.out.println("Page 1: " + page1.getContent().collect(Collectors.toList()));
50
 
          
51
        Page<Hero> page2 = page1.next();
52
 
          
53
        System.out.println("Page 2: " + page2.getContent().collect(Collectors.toList()));
54
 
          
55
        Page<Hero> page3 = page1.next();
56
        System.out.println("Page 3: " + page3.getContent().collect(Collectors.toList()));
57
    }
58
}


A fluent API is amazing and safe to write and reads queries for a NoSQL database, but how about query by text? While a fluent API is safer, it’s sometimes verbose. You know what, though? Jakarta NoSQL has support to query by text that includes PrepareStatement where, as a Java Developer, you can set the parameter dynamically.

Java
xxxxxxxxxx
1
53
 
1
import jakarta.nosql.mapping.PreparedStatement;
2
import jakarta.nosql.mapping.document.DocumentTemplate;
3
import com.google.common.collect.Sets;
4
 
          
5
import javax.enterprise.context.ApplicationScoped;
6
import javax.inject.Inject;
7
import java.util.Arrays;
8
import java.util.stream.Collectors;
9
import java.util.stream.Stream;
10
 
          
11
@ApplicationScoped
12
public class TextService {
13
 
          
14
    @Inject
15
    private DocumentTemplate template;
16
 
          
17
    public void execute() {
18
 
          
19
        Hero iron = new Hero("Iron man", 32, Sets.newHashSet("Rich"));
20
        Hero thor = new Hero("Thor", 5000, Sets.newHashSet("Force", "Thunder"));
21
        Hero captainAmerica = new Hero("Captain America", 80, Sets.newHashSet("agility",
22
                "strength", "speed", "endurance"));
23
        Hero spider = new Hero("Spider", 18, Sets.newHashSet("Spider"));
24
 
          
25
        template.query("delete from Hero where _id in ('Iron man', 'Thor', 'Captain America', 'Spider')");
26
        template.insert(Arrays.asList(iron, thor, captainAmerica, spider));
27
        //query younger
28
        PreparedStatement prepare = template.prepare("select * from Hero where age < @age");
29
        prepare.bind("age", 20);
30
 
          
31
        Stream<Hero> youngStream = prepare.getResult();
32
 
          
33
        Stream<Hero> seniorStream = template.query("select * from Hero where age > 20");
34
 
          
35
        Stream<Hero> powersStream = template.query("select * from Hero where powers in ('Strength')");
36
 
          
37
        Stream<Hero> allStream = template.query("select * from Hero");
38
 
          
39
        Stream<Hero> skipLimitStream = template.query("select * from Hero skip 0 limit 1 order by _id asc");
40
 
          
41
        String yongHeroes = youngStream.map(Hero::getName).collect(Collectors.joining(","));
42
        String seniorsHeroes = seniorStream.map(Hero::getName).collect(Collectors.joining(","));
43
        String allHeroes = allStream.map(Hero::getName).collect(Collectors.joining(","));
44
        String skipLimitHeroes = skipLimitStream.map(Hero::getName).collect(Collectors.joining(","));
45
        String powersHeroes = powersStream.map(Hero::getName).collect(Collectors.joining(","));
46
 
          
47
        System.out.println("Young result: " + yongHeroes);
48
        System.out.println("Seniors result: " + seniorsHeroes);
49
        System.out.println("Powers Strength result: " + powersHeroes);
50
        System.out.println("All heroes result: " + allHeroes);
51
        System.out.println("All heroes skip result: " + skipLimitHeroes);
52
    }
53
}


What do you think? Too complex? Don’t worry, we can simplify it for you with a Repository. A repository abstraction is here to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.


Java
xxxxxxxxxx
1
77
 
1
import jakarta.nosql.mapping.Page;
2
import jakarta.nosql.mapping.Pagination;
3
import jakarta.nosql.mapping.Repository;
4
 
          
5
import java.util.stream.Stream;
6
 
          
7
public interface HeroRepository extends Repository<Hero, String> {
8
 
          
9
    Stream<Hero> findAll();
10
 
          
11
    Page<Hero> findAll(Pagination pagination);
12
 
          
13
    Stream<Hero> findByPowersIn(String powers);
14
 
          
15
    Stream<Hero> findByAgeGreaterThan(Integer age);
16
 
          
17
    Stream<Hero> findByAgeLessThan(Integer age);
18
}
19
 
          
20
 
          
21
import jakarta.nosql.mapping.Page;
22
import jakarta.nosql.mapping.Pagination;
23
import com.google.common.collect.Sets;
24
 
          
25
import javax.enterprise.context.ApplicationScoped;
26
import javax.inject.Inject;
27
import java.util.Optional;
28
import java.util.stream.Collectors;
29
import java.util.stream.Stream;
30
 
          
31
import static java.util.Arrays.asList;
32
 
          
33
@ApplicationScoped
34
public class RepositoryService {
35
 
          
36
    @Inject
37
    private HeroRepository repository;
38
 
          
39
    public void execute() {
40
 
          
41
        Hero iron = new Hero("Iron man", 32, Sets.newHashSet("Rich"));
42
        Hero thor = new Hero("Thor", 5000, Sets.newHashSet("Force", "Thunder", "Strength"));
43
        Hero captainAmerica = new Hero("Captain America", 80, Sets.newHashSet("agility",
44
                "Strength", "speed", "endurance"));
45
        Hero spider = new Hero("Spider", 18, Sets.newHashSet("Spider", "Strength"));
46
 
          
47
 
          
48
        repository.save(asList(iron, thor, captainAmerica, spider));
49
        //find by id
50
        Optional<Hero> hero = repository.findById(iron.getName());
51
        System.out.println(hero);
52
 
          
53
        Stream<Hero> youngStream = repository.findByAgeLessThan(20);
54
        Stream<Hero> seniorStream = repository.findByAgeGreaterThan(20);
55
        Stream<Hero> strengthStream = repository.findByPowersIn("Strength");
56
        Stream<Hero> allStream = repository.findAll();
57
 
          
58
        String yongHeroes = youngStream.map(Hero::getName).collect(Collectors.joining(","));
59
        String seniorsHeroes = seniorStream.map(Hero::getName).collect(Collectors.joining(","));
60
        String strengthHeroes = strengthStream.map(Hero::getName).collect(Collectors.joining(","));
61
        String allHeroes = allStream.map(Hero::getName).collect(Collectors.joining(","));
62
 
          
63
        System.out.println("Young result: " + yongHeroes);
64
        System.out.println("Seniors result: " + seniorsHeroes);
65
        System.out.println("Strength result: " + strengthHeroes);
66
        System.out.println("All heroes result: " + allHeroes);
67
 
          
68
        //Pagination
69
        Pagination pagination = Pagination.page(1).size(1);
70
        Page<Hero> page1 = repository.findAll(pagination);
71
        System.out.println("Page 1: " + page1.getContent().collect(Collectors.toList()));
72
        Page<Hero> page2 = page1.next();
73
        System.out.println("Page 2: " + page2.getContent().collect(Collectors.toList()));
74
        Page<Hero> page3 = page1.next();
75
        System.out.println("Page 3: " + page3.getContent().collect(Collectors.toList()));
76
    }
77
}


This concludes the first part of our post, introducing the concept behind Jakarta and NoSQL, and the document API with MongoDB. In part two, we’ll talk about cloud-native, and how to easily move this application to the cloud using Platform.sh. If you’re curious and don’t mind a spoiler, you can take a look at the sample code on your repository.

Further Reading

Moving Jakarta Forward: Jakarta NoSQL Approved as an EE4J Project

Jakarta NoSQL: The Main Idea Behind the API

Topics:
java ,cloud native ,paas ,jakarta ee ,jnosql ,mongodb ,jakarta nosql

Published at DZone with permission of Otavio Santana , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}