BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Introducing Jakarta NoSQL

Introducing Jakarta NoSQL

Leia em Português

Lire ce contenu en français

Bookmarks

Recently approved as an EE4J project, Jakarta NoSQL is a specification in Jakarta EE to help developers create enterprise-grade applications using Java and NoSQL technologies. JNoSQL is the reference implementation of Jakarta NoSQL, providing a set of APIs and a standard implementation for a series of NoSQL databases, such as Cassandra, MongoDB, Neo4J, CouchDB, and OrientDB, among others.

Jakarta NoSQL consists of a Communication Layer (Diana), which brings a set of APIs designed for defining the communication with NoSQL databases. It contains four modules according to each NoSQL database type: key-value, column family, document, and graph; and a Mapping Layer (Artemis), which provides a series of APIs to help developers integrate Java applications with NoSQL databases. The mapping layer is annotation-driven and uses technologies like CDI and Bean Validation, making it simple for developers to use. It is possible to compare the mapping layer with JPA/Hibernate in the traditional RDBMS world.

(Image taken from github.com/eclipse-ee4j/nosql)

Let's go a little deeper and explore how to communicate with key-value, column family, document, and graph NoSQL databases.

The definition of an Entity is relatively similar to JPA. You basically use @Entity, @Id, @Column and so on:

@Entity
public class Person {

  @Id
  private long id;

  @Column
  private String name;

  @Column
  private List phones;
}

Repositories looks like Spring Data repositories, where you extend a Repository<T, ID>:

public interface PersonRepository extends Repository {

  List<Person> findByName(String name);

  Stream<Person> findByPhones(String phone);
}

However, from this point on, things change, since the Maven dependencies change according to the type of NoSQL database being used, as well the setup configuration and how we inject the repository in our services.

Let's compare the differences between column and document NoSQL databases:

Column

The following are the Maven artifacts:

<dependency>
   <groupId>org.jnosql.artemis</groupId>
   <artifactId>artemis-column</artifactId>
   <version>0.0.9</version>
</dependency>
<dependency>
   <groupId>org.jnosql.diana</groupId>
   <artifactId>cassandra-driver</artifactId>
   <version>0.0.9</version>
</dependency>

The following is a producer example used to set up the ColumnFamilyManager:

@ApplicationScoped
public class ColumnFamilyManagerProducer {

  private static final String KEY_SPACE = "developers";
  private ColumnConfiguration<> cassandraConfiguration;
  private ColumnFamilyManagerFactory managerFactory;

  @PostConstruct
  public void init() {
    cassandraConfiguration = new CassandraConfiguration();
    managerFactory = cassandraConfiguration.get();
  }

  @Produces
  public ColumnFamilyManager getManagerCassandra() {
    return managerFactory.get(KEY_SPACE);
  }
}

And finally, an example of how to execute some inserts/queries:

Person person = Person.builder()
  .withPhones(Arrays.asList("234", "432"))
  .withName("Name")
  .withId(id)
  .build();

//using ColumnTemplate
ColumnTemplate columnTemplate =  container.select(CassandraTemplate.class).get();
Person saved = columnTemplate.insert(PERSON);
System.out.println("Person saved" + saved);

ColumnQuery query = select().from("Person").where(eq(Column.of("id", 1L))).build();

Optional<Person> person = columnTemplate.singleResult(query);
System.out.println("Entity found: " + person);

//using PersonRepository
PersonRepository repository = container.select(PersonRepository.class).select(ofColumn()).get();
Person saved = repository.save(PERSON);
System.out.println("Person saved" + saved);

Optional<Person> person = repository.findById(1L);
System.out.println("Entity found: " + person);

Document

The following are the Maven artifacts:

<dependency>
   <groupId>org.jnosql.artemis</groupId>
   <artifactId>artemis-document</artifactId>
   <version>0.0.9</version>
</dependency>
<dependency>
   <groupId>org.jnosql.diana</groupId>
   <artifactId>mongodb-driver</artifactId>
   <version>0.0.9</version>
</dependency>

The following is a producer example used to set up the the DocumentCollectionManager:

@ApplicationScoped
public class DocumentCollectionManagerProducer {

  private static final String COLLECTION = "developers";
  private DocumentConfiguration configuration;
  private DocumentCollectionManagerFactory managerFactory;

  @PostConstruct
  public void init() {
    configuration = new MongoDBDocumentConfiguration();
    Map<String, Object> settings = Collections.singletonMap("mongodb-server-host-1", "localhost:27017");
    managerFactory = configuration.get(Settings.of(settings));
  }

  @Produces
  public DocumentCollectionManager getManager() {
    return managerFactory.get(COLLECTION);
  }
}

And finally, an example of how to execute some inserts/queries:

Person person = Person.builder()
  .withPhones(Arrays.asList("234", "432"))
  .withName("Name")
  .withId(id)
  .build();

//using DocumentTemplate
DocumentTemplate documentTemplate = container.select(DocumentTemplate.class).get();
Person saved = documentTemplate.insert(person);
System.out.println("Person saved" + saved);

DocumentQuery query = select().from("Person")
  .where(eq(Document.of("_id", id))).build();

Optional<Person> personOptional = documentTemplate.singleResult(query);
System.out.println("Entity found: " + personOptional);

//using PersonRepository
PersonRepository repository = container.select(PersonRepository.class)
  .select(ofDocument()).get();
repository.save(person);

List<Person> people = repository.findByName("Name");
System.out.println("Entity found: " + people);
repository.findByPhones("234").forEach(System.out::println);

More details on Jakarta NoSQL's reference implementation can be found at the JNoSQL page.

There is also a presentation of Jakarta NoSQL on Jakarta One available.

Users who want to contribute can subscribe to the mailing list, or get in touch through Twitter.

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT