Over a million developers have joined DZone.

Eclipse JNoSQL 0.0.4, a Solution to Java in NoSQL Databases

DZone's Guide to

Eclipse JNoSQL 0.0.4, a Solution to Java in NoSQL Databases

Learn about Eclipse JNoSQL, a Java framework that streamlines the integration of a Java application with the NoSQL database.

· Database Zone ·
Free Resource

Databases are better when they can run themselves. CockroachDB is a SQL database that automates scaling and recovery. Check it out here.

Eclipse JNoSQL is a Java framework that streamlines the integration of a Java application with the NoSQL database. It defines a set of APIs to interact with the NoSQL database and provides a standard implementation for most NoSQL databases. This clearly helps to achieve very low coupling with the underlying NoSQL technologies used in applications.

The project has two layers:

  1. Communication API: These are set to APIs that define communication with NoSQL database. In the traditional RDBMS world, these can be compared with JDBC APIs. This API set contains four modules with each one representing a NoSQL database storage type like Key-Value pair, Column Family etc.
  2. Mapping API: These are the APIs that help developers integrate their Java application with the NoSQL database. This layer is annotation-driven and uses technologies like CDI and Bean Validations to make it simpler for developers. In the traditional RDBMS world, this layer can be compared to JPA or ORM frameworks.

A Standard Easy-to-Use Extension

Eclipse JNoSQL API has an easy interface and it's easy to implement to a new database.

This particular behavior in a NoSQL database matters — that why the API is extensible.

Image title


The modules project was the most impacting change in the project, so each type has a particular module. Also, there're the bean validation module and configuration, when you would like to read configuration from either XML or JSON by @ConfigurationUnit annotation.


Improves the Query API in Document and Column Database Types

There are improvements in the fluent API to query in both document and column to select and delete entities.

ColumnQuery query = select().from(columnFamily).where("name").eq(name).or("age").gt(10).build();
ColumnQuery query = select().from(columnFamily).where("name").eq(name).and("age").gt(10).build();
ColumnQuery query = select().from(columnFamily).where("name").not().eq(name).build();
ColumnQuery query = select().from(columnFamily).where("salary").between(valueA, valueB).build();
ColumnDeleteQuery query = delete().from(columnFamily).where("name").eq(name).build();
ColumnDeleteQuery query = delete().from(columnFamily).where("name").not().eq(name).build();
ColumnDeleteQuery query = delete().from(columnFamily).where("name").eq(name).and("age").gt(10).build();
ColumnDeleteQuery query = delete().from(columnFamily).where("name").eq(name).or("age").gt(10).build();
DocumentQuery query = select().from(columnFamily).where("name").eq(name).or("age").gt(10).build();
DocumentQuery query = select().from(columnFamily).where("name").eq(name).and("age").gt(10).build();
DocumentQuery query = select().from(columnFamily).where("name").not().eq(name).build();
DocumentQuery query = select().from(columnFamily).where("salary").between(valueA, valueB).build();

DocumentDeleteQuery query = delete().from(columnFamily).where("name").eq(name).build();
DocumentDeleteQuery query = delete().from(columnFamily).where("name").not().eq(name).build();
DocumentDeleteQuery query = delete().from(columnFamily).where("name").eq(name).and("age").gt(10).build();
DocumentDeleteQuery query = delete().from(columnFamily).where("name").eq(name).or("age").gt(10).build();

New Methods to columntemplate and documenttemplate

Now, these classes have find and delete by ID.

It's also available to individual templates asynchronous.

ColumnTemplateAsync template =//new instance...;
Consumer<Optional<User>> callback = o → o.ifPresent(System.out::println);
Optional<User> user = template.find(User.class, 10L, callback);
Consumer<Void> callback = v → System.out.println(“Deleted”);
template.delete(User.class, 10, callback);

DocumentTemplateAsync template =//new instance...;
Consumer<Optional<User>> callback = o → o.ifPresent(System.out::println);
Optional<User> user = template.find(User.class, 10L, callback);
Consumer<Void> callback = v → System.out.println(“Deleted”);
template.delete(User.class, 10, callback);

Query With Object Mapper to Document and Column Mapping API

In the Artemis, there's the query mapper, which implements the same query builder. However, it maps each object field to a native one.

public class God {

    private String name;

    private String power;

   private ColumnQueryMapperBuilder mapperBuilder;

   public void query() {
   ColumnQuery query = mapperBuilder.selectFrom(God.class)

     ColumnDeleteQuery deleteQuery = mapperBuilder.deleteFrom(God.class)
   private DocumentQueryMapperBuilder mapperBuilder;

   public void query() {
   DocumentQuery query = mapperBuilder.selectFrom(God.class)

     DocumentDeleteQuery deleteQuery = mapperBuilder.deleteFrom(God.class)

New Extensions to Capture Particular Behavior From a NoSQL Database

The core concept of JNoSQL is basically that it has a common API; however, an extensible one would make it easier to use specific behavior because this really matters in a NoSQL world. There are new features to Cassandra, ArangoDB, Hazelcast, and OrientDB database. In this version, there is support for AQL, Arango Query language, within JNoSQL.

interface PersonRepository extends ArangoDBRepository<Person, String> {

  @AQL("FOR p IN Person RETURN p")
  List<Person> findAll();

  @AQL("FOR p IN Person FILTER p.name = @name RETURN p")
  List<Person> findByName(@Param("name") String name);

interface PersonAsyncRepository extends ArangoDBRepositoryAsync<Person, String> {

  @AQL("FOR p IN Person FILTER p.name = @name RETURN p")
  void queryName(@Param("name") String name, Consumer<List<Person>> callBack);


Also is possible to use the Param type in the repository class for both Cassandra and OrientDB.

interface PersonRepository extends CassandraRepository<Person, String> {

  @CQL("select * from Person where age = :age")
  List<Person> findByAge(@Param("age") Integer age);

interface PersonAsyncRepository extends CassandraRepositoryAsync<Person, String> {
  @CQL("select * from Person where name= :name")
  void queryName(@Param("name") String name, Consumer<List<Person>> callBack);
interface PersonRepository extends OrientDBCrudRepository<Person, String> {

  @SQL("select * from Person")
  List<Person> findAll();

  @SQL("select * from Person where name = ?")
  List<Person> findByName(String name);

  @SQL("select * from Person where age = :age")
  List<Person> findByAge(@Param("age") Integer age);

interface PersonAsyncRepository extends OrientDBCrudRepositoryAsync<Person, String> {

  @SQL("select * from Person where name = ?")
  void queryName(String name, Consumer<List<Person>> callBack);

  @SQL("select * from Person where age = :age")
  void queryName(@Param("age") Integer age, Consumer<List<Person>> callBack);


Hazelcast also has a Query syntax resource:

interface PersonRepository extends HazelcastRepository<Person, String> {

        List<Person> findActive();

        @Query("name = :name AND age = :age")
        Set<Person> findByAgeAndInteger(@Param("name") String name, @Param("age") Integer age);

HazelcastTemplate is a specialization of the Key-Value template that allows using the SQL syntax query.

      Collection<Person> people = template.query("active");
      Collection<Person> people2 = template.query("age = :age", singletonMap("age", 10));
      Collection<Person> people3 = template.query(Predicates.equal("name",  "Poliana"));

Diving Deep Into the Model With Graph API

As far graph databases go, NoSQL is the kind that allows more complexity deep in the relationship. This API comes with more integration with Apache Tinkerpop.

The GraphTemplate has new methods that recover the edges of an entity from either itself or its ID.

Person otavio = graphTemplate.insert(builder().withAge().withName("Otavio").build());

Animal dog = graphTemplate.insert(new Animal("dog"));
Book cleanCode = graphTemplate.insert(Book.builder().withName("Clean code").build());

EdgeEntity likes = graphTemplate.edge(otavio, "likes", dog);
EdgeEntity reads = graphTemplate.edge(otavio, "reads", cleanCode);

Collection<EdgeEntity> edges1 = graphTemplate.getEdges(otavio, Direction.BOTH);
Collection<EdgeEntity> edges2 = graphTemplate.getEdges(otavio, Direction.BOTH, "reads");
Collection<EdgeEntity> edges3 = graphTemplate.getEdges(otavio, Direction.BOTH, () -> "likes");
Collection<EdgeEntity> edges4 = graphTemplate.getEdges(otavio, Direction.OUT);
Collection<EdgeEntity> edges5 = graphTemplate.getEdges(cleanCode, Direction.IN);

Collection<EdgeEntity> edges6 = graphTemplate.getEdgesById(otavio.getId(), Direction.BOTH);
Collection<EdgeEntity> edges7 = graphTemplate.getEdgesById(otavio.getId(), Direction.BOTH, "reads");
Collection<EdgeEntity> edges8 = graphTemplate.getEdgesById(otavio.getId(), Direction.BOTH, () -> "likes");
Collection<EdgeEntity> edges9 = graphTemplate.getEdgesById(otavio.getId(), Direction.OUT);
Collection<EdgeEntity> edges10 = graphTemplate.getEdgesById(cleanCode.getId(), Direction.IN);

Graph Queries Improvements

There's an advance in the graph queries in this version such as for define order, predicate, loop resource.


Stream<EdgeEntity> edges1 = graphTemplate.getTraversalEdge().has(property)

Stream<EdgeEntity> edges2 = graphTemplate.getTraversalEdge().has(property)

Stream<Book> books1 = graphTemplate.getTraversalVertex().hasLabel(Book.class)

Stream<Book> books2 = graphTemplate.getTraversalVertex().hasLabel(Book.class)


  long count = graphTemplate.getTraversalVertex()

  EdgeEntity reads=//instance;
  long count = graphTemplate.getTraversalEdge().filter(reads::equals).count();


List<Person> people = graphTemplate.getTraversalVertex().limit(2).<Person>stream()
                .collect(toList());//limit by 2 elements

List<Person> people = graphTemplate.getTraversalVertex().range(1,3).<Person>stream()
                .collect(toList());//a range of one inclusive and three exclusive


In the graph query, there're two ways to make a loop; the first one defines times to repeat an operation and repeats the process until the condition is accurate.

        Animal lion = graphTemplate.insert(new Animal("lion"));
        Animal snake = graphTemplate.insert(new Animal("snake"));
        Animal mouse = graphTemplate.insert(new Animal("mouse"));
        Animal plant = graphTemplate.insert(new Animal("plant"));

        graphTemplate.edge(lion, "eats", snake);
        graphTemplate.edge(snake, "eats", mouse);
        graphTemplate.edge(mouse, "eats", plant);

        Optional<Animal> topAnimal = graphTemplate.getTraversalVertex()
        Optional<Animal> plantResult = graphTemplate
                .until().has("name", "plant").next();

What's Next?

The next step is to submit this as standard in the Java world through the JSR. The community effort is significant at this stage, so now is the opportunity to join the email list and also support this JSR.


Databases should be easy to deploy, easy to use, and easy to scale. If you agree, you should check out CockroachDB, a scalable SQL database built for businesses of every size. Check it out here. 

jnosql ,nosql ,eclipse ,javaee ,database ,tutorial

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}