Logo os JNoSQL: image of Duke, Java's cartoon mascot, with a bow and arrow pointing to the right

The Eclipse JNoSQL is a framework with the goal to help developers in creating enterprise-ready applications using Java and NoSQL technologies. It enables them to create scalable applications while maintaining low coupling with the underlying NoSQL technology.

View on GitHub

Minimum requirement

  • Java 8 higher
  • CDI implementation e.g.: Weld
  • Bean Validation implementation e.g.: Hibernate Validator when enabling Bean validation (optional)
  • JCache implementation e.g.: JSR107 Cache RI when enabling second level cache (optional)
  • JSON-B implementation e.g.: Eclipse Yasson When it needs JSON binding to either read a JSON configuration's file, or it needs to serialize or deserialize values to a database implementation.

Start with Key-value

Add the Eclipse JNoSQL Artemis dependency
          
            <dependency>
              <groupId>org.jnosql.artemis</groupId>
              <artifactId>artemis-core</artifactId>
              <version>version</version>
            </dependency>
          
        
Choose any key-value vendor. e.g:
          
            <dependency>
              <groupId>org.jnosql.diana</groupId>
              <artifactId>hazelcast-driver</artifactId>
              <version>version</version>
            </dependency>
          
        
Use annotation to define either the Id and the entity name such as JPA.
          
            @Entity
            public class User implements Serializable {

            @Id
            private String userName;

            private String name;

            private List<String> phones;
            //The getter and setter are not required.
            //However, the class must have a non-private constructor with no parameters.
          }
        
      
Make an eligible BucketManager by the Produces method BucketManager.
        
         @ApplicationScoped
         public class BucketManagerProducer {

         private static final String BUCKET = "developers";

         private KeyValueConfiguration configuration;

         private BucketManagerFactory managerFactory;

         @PostConstruct
         public void init() {
           configuration = new HazelCastKeyValueConfiguration();
           Map<String, Object> settings = singletonMap("hazelcast-instanceName", "hazelcast");
           managerFactory = configuration.get(Settings.of(settings));
        }

         @Produces
         public BucketManager getManager() {
            return managerFactory.getBucketManager(BUCKET);
       }
   }

   
  
That's it, it's ready to use with CDI with a Key-value nosql database.
          
          public class App {

              private static final User USER = User.builder().
                      withPhones(Arrays.asList("234", "432"))
                      .withUsername("username")
                      .withName("Name")
                      .build();

              public static void main(String[] args) {

                  try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
                      KeyValueTemplate keyValueTemplate = container.select(KeyValueTemplate.class).get();
                      User userSaved = keyValueTemplate.put(USER);
                      System.out.println("User saved: " + userSaved);
                      Optional<User> user = keyValueTemplate.get("username", User.class);
                      System.out.println("Entity found: " + user);
                  }
              }

              private App() {
              }
          }
     

      
          
            public class UserService {

                @Inject
                private KeyValueTemplate template;


              public User put(User user) {
                  return template.put(user);
              }

              public Optional<User> find(String id) {
                  return template.get(id, User.class);
              }
            }
     
    
Create your own repository
        
       public interface UserRepository extends Repository<User, String> {}
   
  
Actually, Eclipse JNoSQL will handle that for you.
          
         public class App2 {

            private static final User USER = User.builder().
                    withPhones(Arrays.asList("234", "432"))
                    .withUsername("username")
                    .withName("Name")
                    .build();

            public static void main(String[] args) {

                try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

                    UserRepository repository = container.select(UserRepository.class, DatabaseQualifier.ofKeyValue()).get();
                    repository.save(USER);
                    Optionaly<User> user = repository.findById("username");
                    System.out.println("User found: " + user);
                    System.out.println("The user found: " + repository.existsById("username"));
                }
            }

          private App2() {
          }
      }

     
    
        
          public class UserService {

              @Inject
              @Database(DatabaseType.KEY_VALUE)
              private UserRepository repository;


              public User save(User user) {
                  return repository.save(user);
              }

              public Optional<User> find(String id) {
                  return repository.findById(id);
              }
          }
   
  

Start with Column

Add the Eclipse JNoSQL Artemis dependency
          
            <dependency>
              <groupId>org.jnosql.artemis</groupId>
              <artifactId>artemis-core</artifactId>
              <version>version</version>
            </dependency>
          
        
Choose any column vendor. e.g:
          
            <dependency>
              <groupId>org.jnosql.diana</groupId>
              <artifactId>cassandra-driver</artifactId>
              <version>version</version>
            </dependency>
          
        
Use annotation to define either the Id, the column fields and the entity name such as JPA.
          
           @Entity("Person")
           public class Person {

            @Id("id")
            private long id;

            @Column
            private String name;

            @Column
            private List<String> phones;
            //The getter and setter are not required.
            //However, the class must have a non-private constructor with no parameters.
           }
        
      
Make an eligible ColumnFamilyManager by the Produces method 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);
              }

          }


   
  
That's it, it's ready to use with CDI with a column nosql database.
          
          public class App {

          private static final Person PERSON = Person.builder().
                  withPhones(Arrays.asList("234", "432"))
                  .withName("Name")
                  .withId(1)
                  .withIgnore("Just Ignore").build();

          public static void main(String[] args) {

              try(SeContainer container = SeContainerInitializer.newInstance().initialize()) {
                  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);

              }
          }

          private App() {}
      }

     

      
          
            public class PersonService {

               @Inject
               private ColumnTemplate template;


              public Person insert(Person person) {
                  return template.insert(person);
              }

              public Optional<Person> find(Long id) {
                  ColumnQuery query = select().from("Person").where("id").eq(id).build();
                  return template.singleResult(query);
              }
            }
     
    
Create your own repository
        
       public interface PersonRepository extends Repository<Person, Long> {}
   
  
Actually, JNoSQL will handle that for you.
          
            public class App2 {

                private static final Person PERSON = Person.builder().
                        withPhones(Arrays.asList("234", "432"))
                        .withName("Name")
                        .withId(1)
                        .build();

                public static void main(String[] args) {

                    try(SeContainer container = SeContainerInitializer.newInstance().initialize()) {
                        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);

                    }
                }

                private App2() {}
            }
     
    
        
          public class PersonService {

              @Inject
              @Database(DatabaseType.COLUMN)
              private PersonRepository repository;


              public Person save(Person person) {
                  return repository.save(person);
              }

              public Optional<Person> find(Long id) {
                  return repository.findById(id);
              }
          }
   
  

Start with document

Add the Eclipse JNoSQL Artemis dependency
          
            <dependency>
              <groupId>org.jnosql.artemis</groupId>
              <artifactId>artemis-core</artifactId>
              <version>version</version>
            </dependency>
          
        
Choose any document vendor. e.g:
          
            <dependency>
              <groupId>org.jnosql.diana</groupId>
              <artifactId>mongodb-driver</artifactId>
              <version>version</version>
            </dependency>
          
        
Use annotation to define either the Id, the column fields and the entity name such as JPA.
          
           @Entity("Person")
           public class Person {

            @Id("id")
            private long id;

            @Column
            private String name;

            @Column
            private Address address;

            @Column
            private List<String> phones;
            //The getter and setter are not required.
            //However, the class must have a non-private constructor with no parameters.
           }
        
        
          @Embeddable
          public class Address {

            @Column
            private String street;

            @Column
            private String city;

            @Column
            private Integer number;

          } 
        
      
Make an eligible DocumentCollectionManager by the Produces method DocumentCollectionManager.
        
          @ApplicationScoped
          public class DocumentCollectionManagerroducer {

              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);

              }

          }


   
  
That's it, it's ready to use with CDI with a document nosql database.
          
           public class App {


              public static void main(String[] args) {

                  Random random = new Random();
                  Long id = random.nextLong();
                  try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

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

                      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);

                  }
              }

              private App() {
              }
          }

     

      
          
            public class PersonService {

               @Inject
               private DocumentTemplate template;


              public Person insert(Person person) {
                  return template.insert(person);
              }

              public Optional<Person> find(Long id) {
                  DocumentQuery query = select().from("Person").where("id").eq(id).build();
                  return template.singleResult(query);
              }
            }
     
    
Create your own repository
        
       public interface PersonRepository extends Repository<Person, Long> {

       List<Person> findByName(String name);

       Stream<Person> findByPhones(String phone);
     }
   
  
Actually, JNoSQL will handle that for you.
          
            public class App2 {


            public static void main(String[] args) {

                Random random = new Random();
                Long id = random.nextLong();

                try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {

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

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

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

                }
            }

            private App2() {
            }
        }

     
    
        
          public class PersonService {

              @Inject
              @Database(DatabaseType.DOCUMENT)
              private PersonRepository repository;


              public Person save(Person person) {
                  return repository.save(person);
              }

              public Optional<Person> find(Long id) {
                  return repository.findById(id);
              }
          }
   
  

Start with Graph

Add the Eclipse JNoSQL Artemis dependency
          
            <dependency>
              <groupId>org.jnosql.artemis</groupId>
              <artifactId>graph-extension</artifactId>
              <version>version</version>
            </dependency>
          
        
Choose any graph with TinkerPop vendor. e.g:
          
            <dependency>
              <groupId>org.apache.tinkerpop</groupId>
              <artifactId>gremlin-core</artifactId>
              <version>version</version>
            <dependency>
            <dependency>
              <groupId>org.janusgraph</groupId>
              <artifactId>janusgraph-core</artifactId>
              <version>version</version>
            <dependency>
            <dependency>
              <groupId>org.janusgraph</groupId>
              <artifactId>janusgraph-berkeleyje</artifactId>
              <version>version</version>
            <dependency>
            <dependency>
              <groupId>org.janusgraph</groupId>
              <artifactId>janusgraph-lucene</artifactId>
              <version>version</version>
            <dependency>
          
        
Use annotation to define either the Id, the column fields and the entity name such as JPA.
          
          @Entity
          public class Person {

              @Id
              private Long id;

              @Column
              private String name;

              @Column
              private int age;

              @Column
              private String occupation;

              @Column
              private Double salary;
            //The getter and setter are not required.
            //However, the class must have a non-private constructor with no parameters.
           }
        
      
Make an eligible Graph by the Produces method Graph.
        
          @ApplicationScoped
          public class GraphProducer {

              private static final String FILE_CONF = "conf/janusgraph-berkeleyje-lucene.properties";

              private Graph graph;


              @PostConstruct
              public void init() {
                  JanusGraph janusGraph = JanusGraphFactory.open(FILE_CONF);
                  GraphTraversalSource g = janusGraph.traversal();
                  if (g.V().count().next() == 0) {
                      GraphOfTheGodsFactory.load(janusGraph);
                  }
                  this.graph = janusGraph;
              }

              @Produces
              @ApplicationScoped
              public Graph getGraph() {
                  return graph;
              }

              public void close(@Disposes Graph graph) throws Exception {
                  graph.close();
              }
          }



   
  
That's it, it's ready to use with CDI with a graph nosql database.
          
            public final class MarketingApp {


                private MarketingApp() {
                }


                public static void main(String[] args) {

                    try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
                        GraphTemplate graph = container.select(GraphTemplate.class).get();

                        Person banner = graph.insert(builder().withAge(30).withName("Banner")
                                .withOccupation("Developer").withSalary(3_000D).build());

                        Person natalia = graph.insert(builder().withAge(32).withName("Natalia")
                                .withOccupation("Developer").withSalary(5_000D).build());

                        Person rose = graph.insert(builder().withAge(40).withName("Rose")
                                .withOccupation("Design").withSalary(1_000D).build());

                        Person tony = graph.insert(builder().withAge(22).withName("tony")
                                .withOccupation("Developer").withSalary(4_500D).build());


                        graph.edge(tony, "knows", rose).add("feel", "love");
                        graph.edge(tony, "knows", natalia);

                        graph.edge(natalia, "knows", rose);
                        graph.edge(banner, "knows", rose);

                        List<Person> developers = graph.getTraversalVertex()
                                .has("salary", gte(3_000D))
                                .has("age", between(20, 25))
                                .has("occupation", "Developer")
                                .<Person>stream().collect(toList());

                        List<Person> peopleWhoDeveloperKnows = graph.getTraversalVertex()
                                .has("salary", gte(3_000D))
                                .has("age", between(20, 25))
                                .has("occupation", "Developer")
                                .out("knows")
                                .<Person>stream().collect(toList());

                        List<Person> both = graph.getTraversalVertex()
                                .has("salary", gte(3_000D))
                                .has("age", between(20, 25))
                                .has("occupation", "Developer")
                                .outE("knows")
                                .bothV()
                                .<Person>stream()
                                .distinct()
                                .collect(toList());

                        List<Person> couple = graph.getTraversalVertex()
                                .has("salary", gte(3_000D))
                                .has("age", between(20, 25))
                                .has("occupation", "Developer")
                                .outE("knows")
                                .has("feel", "love")
                                .bothV()
                                .<Person>stream()
                                .distinct()
                                .collect(toList());

                        System.out.println("Developers has salary greater than 3000 and age between 20 and 25: " + developers);
                        System.out.println("Person who the Developers target know: " + peopleWhoDeveloperKnows);
                        System.out.println("The person and the developers target: " + both);
                        System.out.println("Developers to Valentine days: " + couple);

                    }
                }

            }

     

      
          
            public class PersonService {

              @Inject
              private GraphTemplate template;


              public Person insert(Person person) {
                  return template.insert(person);
              }

              public Optional<Person> find(Long id) {
                  return template.find(id);
              }
              public EdgeEntity<Person, Person> meet(Person personA, Person personB) {
                  return template.edge(personA, "knows", personB);
              }
          }

     
    
Create your own repository
        
       public interface PersonRepository extends Repository<Person, Long> {

       Stream<Person> findByOccupationAndSalaryGreaterThan(String ocuppation, Double salary);

       Stream<Person> findByAgeBetween(Integer ageA, Integer ageB); 
     }
   
  
Actually, JNoSQL will handle that for you.
          
            public final class MarketingApp2 {


                private MarketingApp2() {
                }


                public static void main(String[] args) {

                    try (SeContainer container = SeContainerInitializer.newInstance().initialize()) {
                        PersonRepository repository = container.select(PersonRepository.class, DatabaseQualifier.ofGraph()).get();

                        Person banner = repository.save(builder().withAge(30).withName("Banner")
                                .withOccupation("Developer").withSalary(3_000D).build());

                        Person natalia = repository.save(builder().withAge(32).withName("Natalia")
                                .withOccupation("Developer").withSalary(5_000D).build());

                        Person rose = repository.save(builder().withAge(40).withName("Rose")
                                .withOccupation("Design").withSalary(1_000D).build());

                        Person tony = repository.save(builder().withAge(22).withName("tony")
                                .withOccupation("Developer").withSalary(4_500D).build());


                        System.out.println("findByOccupationAndSalaryGreaterThan");
                        repository.findByOccupationAndSalaryGreaterThan("Developer", 3_000D)
                                .forEach(System.out::println);
                        System.out.println("findByAgeBetween");
                        repository.findByAgeBetween(20, 30)
                                .forEach(System.out::println);


                    }
                }

            }



     
    
        
          public class PersonService {

              @Inject
              @Database(DatabaseType.GRAPH)
              private PersonRepository repository;


              public Person save(Person person) {
                  return repository.save(person);
              }

              public Optional<Person> find(Long id) {
                  return repository.findById(id);
              }
          }
   
  

References