JNoSQL is an Eclipse project which, according to its definition: “is a Java framework that streamlines the integration of Java applications with NoSQL databases. It defines a set of APIs to interact with NoSQL databases and provides a standard implementation for most NoSQL databases.”
The ambition of JNoSQL is to provide a consistent developer experience across the different NoSQL technologies while enabling to use some specificities.
From a technical standpoint, JNoSQL is made of two layers:
- Artemis: a mapping layer (similar to JPA),
- Diana: a communication layer which sits on top of database drivers.
I am particularly interested in JNoSQL because it is the first project to be the subject of a new Jakarta EE specification. In particular, it will be the first to follow the new Eclipse Foundation Specification Process replacing the Java Community Process.
Hence playing around with JNoSQL is a modest contribution to the future of the Jakarta EE platform.
A few words about the demo project
I have started to follow JNoSQL Hands-on lab at Oracle Code One 2018 and I’ve decided to derive it and to provide a project JNoSQL demo easier for newbies and working with both Java SE and Java EE.
As illustrated in the above mentioned hands-on , JNoSQL offers two ways to interact with a database:
- using a Template,
- using a Repository.
For the sake of simplicity, JNoSQL demo is based on a minimalistic example using MongoDB. It aims at being a quickstart and can easily be extended to other uses cases and databases.
The demo project is based on a Person entity and an Address value object.
The project illustrates some basic operations in different contexts:
- TestTemplateSE: using a Template in Java SE, starting the CDI container programmatically,
- TestTempalteEE: using a Template in Java EE with Arquillian and a remote Payara server,
- TestRepositorySE: using a Repository in Java SE, starting the CDI container programmatically,
- TestRepsoitoryEE: using a Repository in Java EE with Arquillian and a remote Payara server.
There is no beans.xml file, hence the discovery mode is implicitly set to annotated and all CDI classes must be annotated (@ApplicationScoped, @RequestScoped).
The following sofware have been used:
- Java SE 8,
- JNoSQL 0.0.7: as of this date (14 Jan. 2019) JNoSQL 0.0.8 (released in Dec; 2018) is not yet published on Maven central,
- MongoDB server 3.4.18,
- Payara 5.184 for Java EE testing,
- Weld 3.0.5.Final for Java SE testing,
- Lombok 1.84.4 is used to avoid the boiler plate code: getter, setter, constructor…
To run the project “as is”:
- a running MongoDB server is needed in all test cases described below,
- a running Payara 5 server is needed in Java EE test cases. Of course, with small changes in the pom.xml, the demo project can potentially work on any Java EE 8 server: OpenLiberty, WildFly, TomEE …
Using a Template
A Template is an injectable CDI object enabling to run:
- CRUD operations on a single or a list of entities: insert, update and delete,
- Queries in different flavors: select, count, singleResult, prepare, query, including skip and limit directives for pagination.
A template provides great flexibility with the database enabling all kinds of precise queries.
Using a Repository
A Repository is a CDI injectable Java interface that extends JNoSQL Repository. By default, a Repository implements:
- CRUD operations on a single or a list of entities: findById, save (both for insert and update), delete,
- Basic queries: count, existById (for a single or a list of entities), count.
Additional queries can be defined in the interface, returning Stream or List, based on attribute names of entities or value objects:
- findByPhones …
The implementation is auto-magically generated at runtime by JNoSQL. Is seems very similar to DeltaSpike Data.
Template vs Repository?
A Template provides great flexibility to query the database. A Repository has the main benefit of being strongly typed, enabling a consistent developer experience, thanks to its Java interface definition. However it is less powerful in terms of query. For instance, it doesn’t enable to paginate on result sets (with skip and limit directives on select queries). At least, I’ve not been able to find it …
Here are some specific feedbacks coming from this first experience:
- a CDI producer returning a DocumentCollectionManager is needed to inject a Template or a Repository (@ApplicationScoped),
- Diana mongodb-driver has a weird dependency on de.flapdoodle.embed which is a testing tool. This is subject to an open issue on the jnosql-diana-driver project. I’ve excluded it in the pom.xml,
- the @Database annotation is required when using a Repository in Java EE. Warning: if you forget it or if you put a bad value, a weird CDI error happens: WELD-000167: Class PersonRepository is annotated with @ApplicationScoped but it does not declare an appropriate constructor therefore is not registered as a bean! I was ready to open an issue when I realized that I put @Database(DatabaseType.COLUMN) in my code instead of @Database(DatabaseType.DOCUMENT). Curiously, this error does not happen in Java SE and the @Database annotation is not required. Even more, it seems to be ignored.
JNoSQL seems to be a promising solution and a strong basis for a new Jakarta EE specification. It would deserve a better documentation and more examples to facilitate the first experience.
I hope that this small example will enable you to discover JNoSQL and to make the proper decision when choosing between a Repository and a Template.
To make a long story short:
- both can be used in Java SE and Java EE with the same level of functionalities,
- in terms of CRUD operations, they are very similar,
- a Template provides more flexibility when querying the database,
- a Repository has the benefit of being strongly typed, but it is less limited than a template.
Hope this helps!
Leave a Reply