Exploring MongoDB Capabilities With Java Using Jakarta NoSQL 1.0.0-b5
In this tutorial, further explore the integration with Java and NoSQL database with Jakarta NoSQL exploring an application with MongoDB.
Join the DZone community and get the full member experience.
Join For FreeNoSQL is a database solution growing in popularity and maturity in several areas, including several regions on enterprise solutions such as finance and e-commerce. In this tutorial, we will explain how to use MongoDB and Java using Jakarta EE with the newest version of Jakarta NoSQL.
If you are unfamiliar with Jakarta NoSQL, it is a Jakarta specification that aims to make life easier between Java and NoSQL. The main goal is to use commons annotation to map multiple database types that currently support key-value, wide-column, document, and graph.
The Jakarta NoSQL newest version, 1.0.0-b5, has three hot features:
- Support for record
- Simplify database configuration
- Enhance documentation as a first-class citizen
To explore those features, let's create a simple MongoDB application with Jakarta NoSQL and Java SE on the MongoDB instance. The first step is to install and execute the database. To make it smoother, let's run a Docker image.
docker run -d --name mongodb-instance -p 27017:27017 mongo
Once you have the MongoDB running, let's return to the Java application side and include the Maven dependencies. Thus, you need to include CDI, JSON-B, and JSON-P implementations, and furthermore, the Jakarta NoSQL dependency.
We'll create a Book
entity with ISBN, title, author, year, and edition. The book
entity is an immutable case where you don't change it once you release it. Wait, how about a new edition? It is a new book
: thus, we often pay for it.
@Entity
public record Book(@Id String isbn,
@Column("title") String title,
@Column("author") String author,
@Convert(YearConverter.class) @Column("year") Year year,
@Column("edition") int edition) {
public Book nextEdition(String isbn, Year year) {
Objects.requireNonNull(isbn, "isbn is required");
Objects.requireNonNull(year, "year is required");
return new Book(isbn, this.title, this.author, year, this.edition + 1);
}
}
The Book
entity as a record decreases the boilerplate to create an immutable class. It is essential to highlight that the record feature is still a Java class, so you can create methods such as a builder to make it easier to create a record or new edition method as we did.
The next step is the database properties. This new version explores the philosophy of convention over configuration. Consequently, you don't need to use any class anymore. It requires properties to create it. These changes break compatibility with the previous version. Please check the driver properties on the JNoSQL driver repository.
jnosql.document.database=library
jnosql.mongodb.host=localhost:27017
That's it! If you wish to configure it programmatically, you may need to implement the Supplier
of a manager database and define it as an alternative with priority; it is natural if you use CDI.
@Alternative
@Priority(Interceptor.Priority.APPLICATION)
@ApplicationScoped
public class ManagerSupplier implements Supplier<DocumentManager> {
@Produces
public DocumentManager get() {
...
}
}
The next step is to execute it. We'll create the first interaction with MongoDB. We'll use as the first step the Template
interface, which takes the typical behavior among databases.
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
String id = UUID.randomUUID().toString();
long start = System.currentTimeMillis();
Template template = container.select(Template.class).get();
Book book = new Book(id, "Java Concurrency in Practice", " Brian Goetz", Year.of(2006), 1);
template.insert(book);
Optional<Book> optional = template.find(Book.class, id);
System.out.println("The result " + optional);
long end = System.currentTimeMillis() - start;
System.out.println("The total operation is: " + end);
template.delete(Book.class, id);
}
As with any code design decision, the Template
has a limitation on features once it takes the standard behavior among NoSQL database types that Jakarta NoSQL supports. There is a specialization to NoSQL types for document types; there is DocumentTemplate
, where we can explore the capability of document types.
try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
DocumentTemplate template = container.select(DocumentTemplate.class).get();
Book first = new Book(randomUUID().toString(), "Effective Java", "Joshua Bloch",
Year.of(2001), 1);
Book second = first.nextEdition(randomUUID().toString(), Year.of(2008));
Book third = second.nextEdition(randomUUID().toString(), Year.of(2018));
template.insert(List.of(first, second, third));
DocumentQuery query = DocumentQuery.select().from("Book")
.where("title").eq("Effective Java")
.orderBy("year").desc().build();
System.out.println("The Effective java editions: ");
template.select(query).forEach(System.out::println);
template.delete(Book.class, first.isbn());
template.delete(Book.class, second.isbn());
template.delete(Book.class, third.isbn());
}
We could insert and then list all books from the title order by the edition in descending order. The DocumentTemplate
has characteristics for document types where you can explore the particular NoSQL database features even more. Thus there are DocumentTemplate
specializations. You can check several samples on Mapping specializations.
That's it! In this tutorial, you learned how to integrate Java with MongoDB exploring the new features of Jakarta NoSQL. Jakarta NoSQL is working on the next version, where the big bang of Jakarta EE and support for Jakarta Data are expected. The new features bring capabilities that make it more comfortable for an enterprise Java developer exploring NoSQL databases.
References
Opinions expressed by DZone contributors are their own.
Comments