Skip navigation
1 2 3 Previous Next

otaviojava

35 posts

The Eclipse JNoSQL is a framework whose has the goal to help Java developers to create Java EE applications with NoSQL, whereby they can make scalable application beyond enjoy the polyglot persistence. On the version 0.0.3, it releases some improvements, new features and also bugs fixes. This post will cover these new.

 

 

Documentation improvements:

 

 

The documentation is a heart of any open source project, and we keep improving this documentation.

 

 

Communication layer aka Diana

 

 

Improves the structure in Column and Document entities

 

 

A nice improvement was in the performance to find information, avoid duplicates tuples and save memory in the communication entities structures to document and column type. These features make the DocumentEntity and ColumnEntity storage better in mind the documents and columns respectively. Once this change was in the implementation, there is no change in the API.

 

 

Defines a Settings class to use in configurations

 

 

On communication nomenclature, there are the configurations classes. This class must create the entity manager factory. Each provider has specific configurations that belong to it, so the Settings interface came to help on the standard.

 

Settins settings = Settins.of();
settings.put("configuration-key", "configuration-value");
DocumentConfiguration<?> configuration = //instance
DocumentCollectionManagerFactory<?> entityManagerFacoty = configuration.get(settings);

 

 

Improve queries to select and delete at Document and Column type

 

 

Retrieve and delete dates are essential points in a CRUD. This version the calls to those operations there is a fluent API both document and column type.

 

DocumentCondition condition = eq(Document.of("name", "Ada"));
DocumentQuery select = select().from(DOCUMENT_COLLECTION).where(condition).build();
DocumentDeleteQuery delete = delete().from(documentCollection).where(condition).build();
List<DocumentCollectionEntity> documents = entityManager.find(select);
entityManager.delete(delete);

 

Improvements in the mapping API aka Artemis

 

 

Improve extensions

 

 

An essential point on the JNoSQL project are the extensions, as a matter of fact, these extensions matter because to capture the particular behavior of NoSQL database. There is an improvement with Cassandra, Couchbase, Elasticsearch, OrientDB. Thereby the Java developer can use specific behavior using conventions.

 

 

 

Improve call using N1QL [Couchbase]

 

 

A feature of the repository types that makes implementation instead of the Java developers, likewise, just create an interface that extends Repository interface. In the same way, Couchbase has N1QL, whose is look like SQL. Nevertheless, it focuses on JSON queries in Couchbase. To the developers use this resource on Couchbase, there are extensions classes to use it, CouchbaseRepositoryAsync and CouchbaseRepository.

 

 

    interface PersonRepository extends CouchbaseRepository<Person, String> {
     @N1QL("select * from Person")
     List<Person> findAll();

     @N1QL("select * from Person where name = $name")
     List<Person> findByName(@Param("name") String name);
  }

 

The extension will handle and create the implementation/query to you.

 

 

 

We have graph API!

 

tinkerpop-splash.png

Initially, as an extension. On this version is available a graph API to JNoSQL. It uses Apache TinkerPop as communication layer and converts to its entities. The Apache TinkerPop, currently, it works as standard JDBC, but, justs to a graph database. From this resource, there are improvement such as Transaction annotation, queries with gremlin ( A query in TinkerPop and converting to the entity), it defines the edge. To know more about this: Have a fun moment with Graph and Java

 

 

Configurations from ConfigurationUnit annotation

 

A key point to access the database is the configuration. On the configurations, there are pieces of information such as user, password, servers IPs. Those dates are important and, normally, that is not a good practice to put thus in the code. To solve this, now, there is Configuration annotation. It reads configurations from META-INF, jnosql.json by default, then it returns entity manager factory.

 

[
   {
      "description":"The couchbase document configuration",
      "name":"document",
      "provider":"org.jnosql.diana.couchbase.document.CouchbaseDocumentConfiguration",
      "settings":{
         "couchbase-host-1":"localhost",
         "couchbase-user":"root",
         "couchbase-password":"123456"
      }
   },
   {
      "description":"The couchbase key-value configuration",
      "name":"key-value",
      "provider":"org.jnosql.diana.couchbase.key.CouchbaseKeyValueConfiguration",
      "settings":{
         "couchbase-host-1":"localhost",
         "couchbase-user":"root",
         "couchbase-password":"123456"
      }
   }
]

 

 

From this file, it creates entity manager factories.

 

 

  @Inject
  @ConfigurationUnit(name = "document")
  private DocumentCollectionManagerFactory<CouchbaseDocumentCollectionManager> entityManager;
 
  @Inject
  @ConfigurationUnit(name = "key-value")
  private BucketManagerFactory<BucketManager> bucketManager;

 

 

 

 

To conclude, we covered the news that is coming on JNoSQL version 0.0.3 and more features is coming and all help from community matter. As the next version, we're planning modules to the types, once normally the Java developer does not use all the NoSQL types every time also capture more particular behavior such as Arango Query Language, a specific query to ArangoDB.

 

 

Join us!

http://jnosql.org/

untitled-drawing.png

The NoSQL databases have become more popular in several areas, NoSQL has different types that also include Graph. The Graph database has a structure pretty different from relational technology and has a lot of success cases such as recommendation system like in social media with Facebook and Linkedin also it is conservative field as financial one, that has using graph database to avoid fraud. This article will cover what Graph is and how to use it with Java.

 

The Graph Structure

 

graph-structure.png

  • Property: that is the small component in the structure, the property is a tuple where the key is the name, and the value is the information itself.
  • Vertex: That looks like the table in a SQL technology that an unlimited number of properties.
  • Edge: The element that represents the relationship between vertex, it has a small similarity with a relationship in SQL. However, the edge has properties, so a connection deeper than relational technology.

 

The graph direction is another concept pretty important in a graph structure, e.g., you can know a person, despite, this person might not know you.

 

 

  • Out: Vertex -> action -> Vertex the "out" is the "action" direction, moreover the sample: I know the Ironman.
  • In: Vertex <- passive <- the "in" is the reaction course, identically the ironman is known by me.

 

The Graph databases providers

 

The are several graphs provides the most famous one is Neo4J.

 

  • Neo4J
  • ArangoDb
  • Titan
  • OrientDB

 

The APIs

 

The biggest issue when the market has several solutions is the several ways to connecting using API, so each NoSQL provider has itself own solution to connect in the database. So, there is a locking, and every time we need to learn a different API, thereby, the cust to chance is high.

 

 

TinkerPop the Graph Standard

tinkerpop-splash.png

To avoid locking and the previously related problem, we have Tinkerpop. Tinkerpop is an open source solution from Apache Foundation. It's a standard API to do graph database operations, that includes a nice graph query. Currently, the Tinkerpop has more than thirty databases implementation.

 

Graph over relational technology

 

Take the picture below; the goal is to through a hierarchical structure such as food chain.

 

untitled-drawing1.png

How can we do in a relational technology? If you're using a graph that became easier and running gremlin, a Tinkerpop query, the command is:

 

g.V().repeat(out("eats")).times(3);//to go three times in the graph
g.V().repeat(out("eats")) .until(has("name", "grass"));//to go as a "do while" structure

 

That easy, isn't?

 

Nice, but how about my entities?

 

TinkerPop does support Java, however, just with its API and that is not even close of the entities such as Person, Book which the Java developers work.

 

 

JNoSQL

 

jnosql-structure.png

This is why we launched the Eclipse JNoSQL project. A flexible and extensible Java API for connecting to NoSQL databases. With it's easy to interface, and the support to multiple NoSQL models, JNoSQL brings to the Java developer the easy of use and freedom of choice that is a characteristic of the Java ecosystem.

JNoSQL supports all the NoSQL models, like key-value, column family, document-oriented and graph databases. This allows developers to experiment with multiple NoSQL databases, and choose the ones that are better suited to their particular needs. It frees developers from having to commit to a single product and gives the vendors the freedom to innovate without alienating developers.

With the support for more than thirty NoSQL databases and integrating with CDI, JNoSQL quickly became a central integration piece to deal with NoSQL databases in Java.

 

 

The project has two layers:

 

  • The communication API, known as Diana: An API to communicate with the database, similar to JDBC for SQL databases. This API has four specializations, one for each kind of database.
  • The mapping API, known as Artemis: An API to map the data in the database to Java Objects, providing similar functionality to JPA for relational databases. It is annotation and CDI driven and has integration with other technologies such as Bean Validation.

 

JNoSQL and Graph

jnosql.png

 

In the Graph database, JNoSQL has an integration with the Tinkerpop through the mapping API, aka Artemis. So to make this graph below a Java operation:

untitled-drawing-1.png

Create the Entity with the Mapping annotation

 

@Entity
public class Book {
    @Id
    private Long id;
    @Column
   private String name;


//getter and setter
}


@Entity
public class Person {


    @Id
    private Long id;


    @Column
    private String name;


    @Column
    private int age;


    @Column
    private String occupation;


    @Column
    private Double salary;


//getter and setter
}

 

 

Inject the GraphTemplate class

 

@Inject
private GraphTemplate graph;

//to CDI 2.0 with Java SE
GraphTemplate graph = container.select(GraphTemplate.class).get();

 

 

Save the entities

 

Person poliana = Person.builder().withName("Poliana").withAge(25).build();


Book shack = Book.builder().withAge(2007).withName("The Shack").build();


graphTemplate.insert(poliana);
graphTemplate.insert(shack);

 

Create the relationship between them[Edge]

 

EdgeEntity<Person, Book> reads = graphTemplate.edge(poliana, "reads", shack);
reads.add("where", "Brazil");

 

Done, we have our first graph operation.

 

Running query with JNoSQL and TinkerPop

 

Given the scenario:

 

 

1) We're working in a marketing camping and our target is:

 

  • An engineer
  • The salary is higher than 3000
  • The age is between 20 and 25 years old

 

In this scenario both SQL and Tinkerpop easy to do.

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

 

 

The Engineer Friend

 

Once we have our target, the engineer, we want to return the engineer friends. On this next step, the TinkerPop became easier than SQL. We'll keep all the previous parameters with a new parameter query, out("knows").

 

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

 

 

The Engineer love

The fact that the target knows a person isn't enough anymore, we want deeper details in a relationship. That is the power of a Graph database, with Tinkerpop, we just need to replace the last parameter to outE("knows"), the difference is we're mapping the Edge element, so we can do condition on edge properties based, in this case, if the knows label has felt love.

 

 

 

List<Person> love = 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());

 

The whole demo code:

 

https://github.com/JNOSQL/artemis-demo/tree/master/artemis-demo-java-se

 

 

The current version is snapshot version, so it's on snapshot version, to add it to your repository, please, check it:

 

 

https://stackoverflow.com/questions/7715321/how-to-download-snapshot-version-from-maven-snapshot-repository

 

References:

 

Diana is a subproject of the JNoSQL project from Eclipse Foundation. It is a communication layer; this layer has four different API, one to a different database. This post will do an overview of the key-value API.

 

<repositories>
  <repository>
    <id>jnsoql-repo</id>
    <name>JNoSQL Maven Repository</name>
    <url>https://dl.bintray.com/jnosql/maven/</url>
    <layout>default</layout>
  </repository>
</repositories>

 

To demonstrate it will use a Hazelcast driver, so:

 

 

        <dependency>
            <groupId>org.jnosql.diana</groupId>
            <artifactId>hazelcast-driver</artifactId>
            <version>0.0.1</version>
        </dependency>

 

The Column API has the following structure:

 

 

KeyValueConfiguration: The class that has the database configuration, once each database has different setup each storage might have different methods.

BucketManagerFactory:  Class that produces BucketManager.

BucketManager: as JPA, this class handle the entity and does the CRUD operations.

KeyValueEntity: the key-value entity.

 

 

With the Hazelcast driver the developer can do the CRUD operation in Hazelcast at low-level API:

 

public class App {

    public static void main(String[] args) {

        KeyValueConfiguration configuration = new HazelCastKeyValueConfiguration();
        try (BucketManagerFactory managerFactory = configuration.get()) {
            BucketManager bucket = managerFactory.getBucketManager("bucket");
            bucket.
            List<String> list = managerFactory.getList("bucketList", String.class);
            Set<String> set = managerFactory.getSet("bucketSet", String.class);
            Map<String, Integer> map = managerFactory.getMap("bucketList", String.class, Integer.class);
            Queue<String> queue = managerFactory.getQueue("queueList", String.class);
            bucket.put("key", "value");
            Optional<Value> value = bucket.get("key");
        }
    }
}

 

 

An important point at the key-value API is, there are unique structures that Diana supports such as Lits, Queue, Set and Map, really popular to the Java developers.

As can be seen, this post talked the Diana Project, the Communication layer from the JNoSQL project.

 

References:

 

Diana is a subproject of the JNoSQL project from Eclipse Foundation. It is a communication layer; this layer has four different API, one to a different database. This post will do an overview of column API.


 

To demonstrate it will use a Cassandra driver, so:


 

 <dependency>
   <groupId>org.jnosql.diana</groupId>
   <artifactId>cassandra-driver</artifactId>
   <version>0.0.1</version>
 </dependency>


 

The Column API has the following structure:

 

 

  • ColumnConfiguration: The class that has the database configuration, once each database has different setup each storage might have different methods.
  • ColumnManagerFactory: Class that produces ColumnManager.
  • ColumnManager: as JPA, this class handle the entity and does the CRUD operations.
  • ColumnEntity: A column family entity.
  • Column: A ColumnEntity has several columns, that is a tuple with name and value where value may be everything, inclusive, another column, a subcolumn concept.

 


  With the Cassandra driver the developer can do the CRUD operation in Cassandra at low-level API:

 

 

public class App {

 

 

 

 

    public static final String KEY_SPACE = "newKeySpace";

    public static final String COLUMN_FAMILY = "newColumnFamily";

 

 

 

 

public static void main(String[] args) {

        ColumnConfiguration condition = new CassandraConfiguration();




        try (ColumnFamilyManagerFactory managerFactory = condition.get()) {
            ColumnFamilyManager columnEntityManager = managerFactory.get(KEY_SPACE);
            ColumnEntity entity = ColumnEntity.of(COLUMN_FAMILY);
            Column id = Column.of("id", 10 L);
            entity.add(id);
            entity.add(Column.of("version", 0.001));
            entity.add(Column.of("name", "Diana"));
            entity.add(Column.of("options", Arrays.asList(1, 2, 3)));




            columnEntityManager.save(entity);


            ColumnQuery query = ColumnQuery.of(COLUMN_FAMILY);
            query.and(ColumnCondition.eq(id));
            Optional < ColumnEntity > result = columnEntityManager.singleResult(query);
            System.out.println(result);




        }




    }
}

  

 
  To run this sample, a health Cassandra must be running and also put some pieces of information such as Ips to the client connect and the Cassandra structure from CQL in Cassandra driver. To do this, there is the diana-cassandra.properties file at classpath.


 

cassandra-hoster-1=172.17.0.2
cassandra-threads-number=4
cassandra-initial-query-1=CREATE KEYSPACE IF NOT EXISTS newKeySpace WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
cassandra-initial-query-2=DROP TABLE IF EXISTS newKeySpace.newColumnFamily;
cassandra-initial-query-3=CREATE COLUMNFAMILY IF NOT 


 

Tip: An easier way to install a Cassandra instance is using Docker:

https://hub.docker.com/_/cassandra/


 


 

Specializations


 

Cassandra has resources that are beyond the API such as Consistency level and CQL and Diana Support it.

 

public class CassandraApp {








    public static final String KEY_SPACE = "newKeySpace";
    public static final String COLUMN_FAMILY = "newColumnFamily";




    public static void main(String[] args) {




        CassandraConfiguration condition = new CassandraConfiguration();




        try (CassandraDocumentEntityManagerFactory managerFactory = condition.get()) {
            CassandraColumnFamilyManager columnEntityManager = managerFactory.get(KEY_SPACE);
            ColumnEntity entity = ColumnEntity.of(COLUMN_FAMILY);
            Column id = Column.of("id", 10 L);
            entity.add(id);
            entity.add(Column.of("version", 0.001));
            entity.add(Column.of("name", "Diana"));
            entity.add(Column.of("options", Arrays.asList(1, 2, 3)));




            columnEntityManager.save(entity);




            //common implementation
            ColumnQuery query = ColumnQuery.of(COLUMN_FAMILY);
            query.and(ColumnCondition.eq(id));
            List < ColumnEntity > columnEntities = columnEntityManager.find(query, ConsistencyLevel.LOCAL_QUORUM);




            //cassandra implementation
            columnEntityManager.save(entity, ConsistencyLevel.THREE);
            List < ColumnEntity > entities = columnEntityManager.cql("select * from newKeySpace.newColumnFamily");
            CassandraPrepareStatment cassandraPrepareStatment = columnEntityManager.nativeQueryPrepare("select * from newKeySpace.newColumnFamily where id ?");
            List < ColumnEntity > entityList = cassandraPrepareStatment.bind(10 L).executeQuery();
            System.out.println(entities);




        }








    }




}


  As can be seen, this post talked the Diana Project, the Communication layer from the JNoSQL project.


 
  References:


 

A document-oriented database, or document store, is a computer program designed for storing, retrieving and managing document-oriented information, also known as semi-structured data. Document-oriented databases are one of the main categories of NoSQL databases, and the popularity of the term "document-oriented database" has grown[1] with the use of the term NoSQL itself. XML databases are a subclass of document-oriented databases that are optimized to work with XML documents. Graph databases are similar, but add another layer, the relationship, which allows them to link documents for rapid traversal. Document-oriented databases are inherently a subclass of the key-value store, another NoSQL database concept.

Diana is a subproject of the JNoSQL project from Eclipse Foundation. It is a communication layer; this layer has four different API, one to a different database. This post will do an overview of document API.

 

 

To demonstrate it will use a MongoDB driver, so:

 

 

    <dependency>

            <groupId>org.jnosql.diana</groupId>

            <artifactId>mongodb-driver</artifactId>

            <version>0.0.1</version>

     </dependency>

 

The Document API has the following structure:

 

  • DocumentConfiguration: The class that has the database configuration, once each database has different setup each storage might have different methods.
  • DocumentManagerFactory: Class that produces DocumentManager.
  • DocumentManager: as JPA, this class handle the entity and does the CRUD operations.
  • DocumentEntity: A document collection entity.
  • Document: A DocumentEntity has several documents, that is a tuple with name and value where value may be everything, inclusive, another document, a subdocument concept.

 

 

With the MongoDB driver the developer can do the CRUD operation in MongoDB at low-level API:

 

 

public class MongoDBApp {

 

 

    public static final String DATABASE = "default";

    public static final String DOCUMENT_COLLECTION = "person";

 

 

    public static void main(String[] args)  {

        String idValue = UUID.randomUUID().toString();

        DocumentConfiguration configuration = new MongoDBDocumentConfiguration();

        try(DocumentCollectionManagerFactory collectionFactory = configuration.get();) {

            DocumentCollectionManager collectionManager = collectionFactory.get(DATABASE);

 

 

            DocumentEntity entity = DocumentEntity.of(DOCUMENT_COLLECTION);

            entity.add(Document.of("name", "Daniel Soro"));

            entity.add(Document.of("age", 26));

            entity.add(Document.of("_id", idValue));

 

 

            DocumentEntity entitySaved = collectionManager.save(entity);

            Optional<Document> id = entitySaved.find("_id");

 

 

            DocumentQuery query = DocumentQuery.of(DOCUMENT_COLLECTION);

            query.and(DocumentCondition.eq(id.get()));

            List<DocumentEntity> documentsFound = collectionManager.find(query);

 

        }

    }

}

 

 

 

To run this sample, a health MongoDB must be running and also put some information such as the IPs to the client connect to MongoDB driver. To do this, there is the diana-mongodb.properties file at classpath. So, to connect just at the localhost MongoDB instance.

 

 

mongodb-server-host-1=localhost:27017

 

Tip: An easier way to install a MongoDB instance is using Docker:  https://hub.docker.com/_/mongo/

 

 

To show the transparency to change the API, this sample will use a new database Couchbase, just need to add the Couchbase driver:

 

 

        <dependency>

            <groupId>org.jnosql.diana</groupId>

            <artifactId>mongodb-driver</artifactId>

            <version>0.0.1</version>

        </dependency>

 

The Couchbase code:

 

 

public class CouchbaseApp {

 

 

    public static final String DATABASE = "default";

    public static final String DOCUMENT_COLLECTION = "person";

 

 

    public static void main(String[] args)  {

        String idValue = UUID.randomUUID().toString();

        DocumentConfiguration configuration = new CouchbaseDocumentConfiguration();

        try(DocumentCollectionManagerFactory collectionFactory = configuration.get();) {

            DocumentCollectionManager collectionManager = collectionFactory.get(DATABASE);

 

 

            DocumentEntity entity = DocumentEntity.of(DOCUMENT_COLLECTION);

            entity.add(Document.of("name", "Daniel Soro"));

            entity.add(Document.of("age", 26));

            entity.add(Document.of("_id", idValue));

            DocumentEntity entitySaved = collectionManager.save(entity);

            Optional<Document> id = entitySaved.find("_id");

 

 

            DocumentQuery query = DocumentQuery.of(DOCUMENT_COLLECTION);

            query.and(DocumentCondition.eq(id.get()));

            List<DocumentEntity> documentsFound = collectionManager.find(query);

 

        }

    }

}

 

As MongoDB, to run this sample the Java developer must have a health Couchbase running and also set information at the diana-couchbase.properties,  e.g.:

 

 

couchbase-host-1=localhost

couchbase-user=root

couchbase-password=123456

 

 

Tip: The same tip on MongoDB, use the Docker to install Couchbase: https://hub.docker.com/_/couchbase/

 

 

Specializations

 

 

As previously mentioned, an extensible API to get a particular behavior in a NoSQL database is a must. In the Couchbase world has the N1SQL.

 

 

public class CouchbaseApp2 {

 

 

    public static final String DATABASE = "default";

    public static final String DOCUMENT_COLLECTION = "person";

 

 

    public static void main(String[] args)  {

        String idValue = UUID.randomUUID().toString();

        CouchbaseDocumentConfiguration configuration = new CouchbaseDocumentConfiguration();

        try(CouhbaseDocumentCollectionManagerFactory collectionFactory = configuration.get();) {

            CouchbaseDocumentCollectionManager collectionManager = collectionFactory.get(DATABASE);

 

 

            DocumentEntity entity = DocumentEntity.of(DOCUMENT_COLLECTION);

            entity.add(Document.of("name", "Daniel Soro"));

            entity.add(Document.of("age", 26));

            entity.add(Document.of("_id", idValue));

            DocumentEntity entitySaved = collectionManager.save(entity);

            Optional<Document> id = entitySaved.find("_id");

 

 

            JsonObject params = JsonObject.create();

            params.put("id", id.get().get());

            List<DocumentEntity> entities = collectionManager.n1qlQuery("select * from " + DATABASE + " where _id = $id", params);

            System.out.println(entities);

 

        }

    }

}

 

As can be seen, this post talked the Diana Project, the Communication layer from the JNoSQL project. Even with the same API, the behavior can be different such as the way to storage, and the automatic creation of the field "_id" in an insert operation when it does not exist.

 

 

References:

 

diana.png

 

The JNoSQL is a technology whose the goal a standard API to NoSQL database and also looking to the diversity in this database. To get this objective, it has two layers: The communication layer that takes the communication between Java and the Database as JDBC does to the relational world. The abstraction layer that integrates other technologies and is annotation drive as JPA to NoSQL database. This post will cover more details about the communication layer, aka Diana.

Divide and conquer is a small Java strategy and with Diana, that is not different.

 

 

 

Do worth a standard API?

If we take a look at some document databases APIs, we have classes such as:

 

 

  • BaseDocument to the ArangoDB
  • JsonDocument to the couchbase
  • JSON serialization to the Elasticsearch
  • org.bson.Document to the MongoDB
  • ODocument to the OrientDB

 

The class name and qualified are both different from NoSQL vendors, however, if we take a look at the method structure to both add and remove information:

 

 

 

//orientDB

ODocument document = new ODocument(“collection”);

document.field(name, value);

 

//mongodb

Document document = new Document();

document.append(name, value);

 

//couchbase

JsonObject jsonObject = JsonObject.create();

jsonObject.put(name, value);

 

 

//arangodb

BaseDocument baseDocument = new BaseDocument();

baseDocument.addAttribute(name, value);

 

The method has similarity, mainly because the structure is the same, in other words, all document collections have documents and document has the name and value where value can be everything inclusive another document, the subdocument concept.

These affinities in Database happened, mainly, because they have operations in common such as the CRUD operation. But there is not a standard even to nomenclature.

 

  • insert vs. save
  • delete vs. remove
  • find vs. search
  • callback interface to asynchronous callback

 

To TTL definition the vendors have the same problem:

 

 

  • long to seconds
  • int to seconds
  • long to milliseconds
  • int to milliseconds

 

 

The idea behind Diana is an API so that a database change will be easier, also without learning a new nomenclature.

 

 

Document document = Document.of(name, value);

DocumentEntity entity  = DocumentEntity.of(“collection”);

entity.add(document);

 

 

The diversity at NoSQL databases

When we talk about NoSQL takes the difference is a first citizen. So Diana has extensibility to Cassandra driver uses either Cassandra Query Language or consistency level, OrientDB uses the live query, the Elastic search uses a search engine, Couchbase use N1ql, etc. Besides returning the same API structure once all these databases, e.g., uses a document collection structure.

 

 

Available Drivers

 

 

 

At the first version, Diana has drivers to:

 

 

  • ArangoDB
  • Cassandra
  • Coucbase
  • Elasticsearch
  • Hazelcast
  • Hbase
  • MongoDB
  • OrientDB
  • Redis
  • Riak
  • ScyllaDB

 

 

 

References:

 

otaviojava

JNoSQL Q&A

Posted by otaviojava Jan 18, 2017

duke-diana-min.png

What is JNoSQL?

 

 

The JNoSQL project has a goal to create tools to NoSQL development on Java, basically, it tries to create a standard allow the diversity on this kind of database. To make easier this process was created two layers:

 

  • The communication layer (aka Diana): This layer is the communication between the application and the database. This API has four kinds, one for each kind of NoSQL database. Diana does what the JDBC does to a relational database.
  • The abstraction layer (aka Artemis): This project looks like an ORM, it has a goal to make easier a development to a Java developer, it is annotation driven also it has integrations with other technologies such as bean validation. The engine gonna be CDI.

 

Split into two layers has some advantages:

 

 

  • Split the problems: The database providers can take just to communication without cares the abstraction layer as the technology provider can create tools on abstraction layer without cares the communication.
  • Make easier any implementation: A new database can support JNoSQL project, to do this just need to implement the communication API to your specific database.
  • Make components: With components, you can replace any modules without impact the whole applications,  also will be you may replace the database lost lesser code.

 

 

 

Is the plan create a standard?

 

Yes, the main idea is the result of the work on JnoSQL became a JSR. On the first step, just the communication layer will be covered on in a JSR. That’s why there a lot of database provider such as Cassandra, Hazelcast, OrientDB, couchbase, ArangoDB, MongoDB, HBase beyond the community (SouJava, LondoJC, ThinkerPOP and more) are on the project.

 

Can we standard 100%?

 

Even on the SQL database, that has decades on the market, they can’t standard everything. Initially, there are API to cover the entities and also the CRUD operations. There is four kind of API and even database with the same type, Cassandra and HBASE are both column family, there is behavior the has on just a specific database, just Cassandra has both consistency level and Cassandra Query level. So the API must have extensibility to work with the diversity that has on NoSQL world, however, the difference behavior keeps working with the same entity.

 

//both implementations (Hbase and Cassandra)
DocumentEntity entity = DocumentEntity.of("rome");
entity.add(Document.of("name", "Otavio"));
entity.add(Document.of("from", "Brarzil"));
entity.add(Document.of("language", Arrays.asList("English", "Portuguese")));
entity.add(Document.of("_key", "otaviojava"));

entityManager.save(entity);
entityManager.update(entity);

//just on Cassandra
cassandraEntityManager.save(entity, ConsistencyLevel.ALL);
List<ColumnFamilyEntity> entities = entityManager.cql(¨select * from entity¨);

 

What will be covered in the first version?

On this first step, with a JSR, the goal is delivery the entity model, the domain concepts in API and also CRUD methods:

 

  • Insert synchronous, asynchronous, asynchronous with callback and also insert with TTL
  • Update synchronous, asynchronous, asynchronous with callback and also insert with TTL
  • Delete synchronous and asynchronous
  • Retrieve information both synchronous and asynchronous way

 

 

Just the Graph API will have more method, mainly because there is a standard project: The Apache ThinkerPOP. So communication layer gonna have the most stable part of the ThikerPOP and the implementation gonna be an adapter layer, in other words, a database who supports ThinkerPOP will supports automatically JNoSQL.

 

Does JNoSQL worth?

I believe that will the first step to talk more about standards on NoSQL database. We’ll deliver incrementally and be using baby step to quick feedback.

 

What does happen if a database supports two database?

 

It needs to implement two APIs, to each database that it supports, to make easier this process each API has a TCK.

 

What is the current status?

 

The Project has been approved by Eclipse Foundation and we’ll have a presentation about it on JCP EC.

 

How can I help?

 

  • Create Documentation
  • Review documentation
  • Feedback on API
  • Report bugs
  • Give feedback
  • implement new drivers
  • More sample code
  • Help to translate the documentation to other languages
  • Do meetups to talk about this projects
  • Do hackergarten

 

More Information

 

   

   The NoSQL DB is a database that provides a mechanism for storage and retrieval of data which is modeled in means other than the tabular relations used in relational databases. These databases have speed and high scalability. This kind of database has becoming more popular in several applications, that include financial one. As result of increase the number of user the number of vendors are increasing too.



   The NoSQL database is defined basically by the its model of storage, those has four kind:

 

Key-value:

   This database has a structure look like an java.util.Map API, where we can storage any value from a key.

 

  • AmazonDynamo
  • AmazonS3
  • Redis
  • Scalaris
  • Voldemort 
  • Couchbase


     

Document:

   This model can storage any document, without this model be defined previously their structure. This document may be composed by inumerous fields, with many kinds of data, that include a document inside another document. This model is look like either XML or JSON file.

  • AmazonSimpleDb
  • ApacheCouchdb
  • MongoDb
  • Riak
  • Couchbase
  • OrientDB


     

Column:

   This model became popular with the BigTable's paper by Google, with the goal of be a distributed system storage, projected to have either a high scalability and volume.

  • Hbase
  • Cassandra
  • Scylla
  • Clouddata
  • SimpleDb
  • DynamoDB


     

Graph:

In computing, a graph database is a database that uses graph structures for semantic queries with nodes, edges and properties to represent and store data.

  • Neo4j
  • InfoGrid
  • Sones
  • HyperGraphDB
  • OrientDB



     

Multi-model database:

Some database has support to more than one kind of model storage this is the multi model database.

  • OrientDB
  • Couchbase





Standard in SQL

         Looking to Java application that uses relational database. It's a good practice have a layer to be a bridge between a Java application and relationship database: a DAO, the data access object. Talking more about relational database there are APIs such as JPA and JDBC that have some advantages to a Java developer:
     

  • There isn't a lock-in vendor, in other words, with the standard, a database change gonna happen easier and transparency, because we just need to change a simple driver.
  • There isn't necessary to learn a new API for each new database, once there is a common database communication.
  • There isn't impact in that change.






NoSQL Issues: 

    Currently in NoSQL database hasn't standard so a Java developer has some issues:

  • Lock-in vendor
  • To each new database is necessary learn a new API.
  • Any change to another database there is a high impact, once all the communication layer gonna be lost once there isn't a common API. This happen even with the same kind of NoSQL database, for example, a change between a column to another column.

 

There is a huge effort to create a common API to make the Java developers life easier, such as Spring Data, Hibernate ORM and TopLink. The JPA is an API popular in Java world, this is why all solutions try to use it, however this API was not made to NoSQL and it doesn't support all behavior in NoSQL database, many NoSQL haven't transaction and many NoSQL database haven’t support to asynchronous insertion. Basically, you cannot drive a plane with the same car's API.

 

The solution for this case is create a specification that cover the four kind of NoSQL database. The new API should be look like the JPA, once the developer has familiarity with this API, beside add new behavior and new exceptions, when a database has not support to specific resource. Beside the API, another important point is an integration with others Java specifications such as CDI and bean validation.





Conclusion

 

Many NoSQL databases are emerging and also its use by Java developers, in the last survey about Java EE developers, almost 50% of interviewers are already using NoSQL technology. Allow a standard to NoSQL will make easier the life of Java developer once will difficult the lock-in vendor and also is not necessary learn a new API to new database.



References:



javamoney_cup.jpg




The reference implementation of the JSR 354, money-api, release a new version. Moneta, the JSR 354 reference implementation, and Moneta-bp, its backport compatible with Java prior to SE8, run very stable since quite some time. Nevertheless we fixed a few issues.



New factory methods

We also added a few construct methods to all MonetaryAmount T implementations:

  • T zero(CurrencyUnit currency) – Obtains an instance representing zero.
  • T ofMinor(CurrencyUnit currency, long amountMinor) – Obtains an instance from an amount in minor units, in other words, the result of ofMinor(USD, 1234) will be USD 12,34.
  • T ofMinor(CurrencyUnit currency, long amountMinor, int factionDigits) - Obtains an instance from an amount in minor units, in other words, the result of ofMinor(USD, 1234, 2) will be USD 12,34. The difference between with the last method is this method ignore the fraction digits from the CurrencyUnit instance and it uses the fraction digits informed from parameters.


The following snippets shows a few example what you can do now:


MonetaryAmount money = Money.zero(dollar);
MonetaryAmount oneDollar = Money.ofMinor(dollar, 12_34);
MonetaryAmount money = FastMoney.zero(dollar);
MonetaryAmount oneDollar = FastMoney.ofMinor(dollar, 12_34);
MonetaryAmount money = RoundedMoney.zero(dollar);
MonetaryAmount oneDollar = RoundedMoney.ofMinor(dollar, 12_34);



Deprecated MonetaryUtil

We also deprecated the MonetaryUtil class in favour of two new classes:

  1. MonetaryOperator which provides useful implementations for commonly used operators


MonetaryAmount amount = ////USD 12.23
amount.with(MonetaryOperators.majorPart());//USD 12
amount.with(MonetaryOperators.minorPart());//USD 0.23
amount.with(MonetaryOperators.percent(10));//USD 1.223




  1. MonetaryQueries provides useful implementations of queries to extract information from a monetary amount.
MonetaryAmount amount = //USD 12.34 12.32
amount.query(MonetaryQueries.convertMinorPart());//1232
amount.query(MonetaryQueries.extractMajorPart());//12
amount.query(MonetaryQueries.extractMinorPart());//32


This release also contains a new exchange rate provider version to figure out historic exchange rates from the IMF.


CurrencyUnit dollar = Monetary.getCurrency("USD");
CurrencyUnit real = Monetary.getCurrency("BRL");
MonetaryAmount money = FastMoney.of(10, dollar);
MonetaryAmount money2 = FastMoney.of(10, real);
LocalDate localDate = Year.of(2009).atMonth(Month.JANUARY).atDay(9);
ExchangeRateProvider provider = MonetaryConversions.getExchangeRateProvider(ExchangeRateType.IMF_HIST);
ConversionQuery query = ConversionQueryBuilder.of().setTermCurrency(dollar).set(localDate).build();
CurrencyConversion currencyConversion = provider.getCurrencyConversion(query);
MonetaryAmount result = currencyConversion.apply(money2);
MonetaryAmount monetaryAmount = money.add(result);


Changes in MonetaryAmountFormat

We also added new ways to create MonetaryAmountFormat instances so the can be exported with toString() to and be instantiated with this output in a round trip:

MonetaryAmountFormat defaultFormat = MonetaryAmountDecimalFormatBuilder.newInstance().build();
MonetaryAmountFormat patternFormat = MonetaryAmountDecimalFormatBuilder.of("¤ ###,###.00").build();
MonetaryAmountFormat localeFormat = MonetaryAmountDecimalFormatBuilder.of(Locale.US).build();
CurrencyUnit currency = Monetary.getCurrency("BRL");
MonetaryAmount money = Money.of(12, currency);
String format = defaultFormat.format(money);//$12.00
MonetaryAmount moneyParsed = Money.parse(format, defaultFormat);//or using defafult.parse(format);


Backward Compatibility

This is a maintenance release. We checked backward compatibility as part of the CI integrated tooling, so there should be no issues regarding compatibility. The code provided is usage, compile and binary compatible. Explicitly excluded is the usage of code artifacts contained in packages named internal. If you have such usages (we hope: no), please review and test your code before deploying it into production.

Summary

The new version 1.1 of the JSR 354 reference implementation fixes several bugs (most of them minor ones) and comes with a few new features improving developer’s efficiency.
References:



The Stream API , the api whose was born in Java 8, with this resource you can interact with collections easily. This first topic will cover "why we should use it?". To put in practice I will create a simple model, a soccer team.

 


public class Team {
  private List<Player> players;
//…
}

public class Player {

  private String name;

  private int gols;

  private Position position;

//...
}

public enum Position {
GOALKEEPER,DEFENDER, FORWARDS
}

 

 

With this model, the next step is manipulate the soccer player. First this code will use just resources from Java 7. The first method will return just the forwarders.

 


   public List<Player> getForwarders() {
  List<Player> forwarders = new ArrayList<>();
  for (Player player : players) {
    if(player.isFowarder()) {
       forwarders.add(player);
     }
  }
  return Collections.unmodifiableList(forwarders);
  }

 

 

Further, the next method will return just the defenders.

 


    public List<Player> getDefenders() {
  List<Player> defenders = new ArrayList<>();
  for (Player player : players) {
     if(player.isDefender()) {
        defenders.add(player);
     }
   }
  return Collections.unmodifiableList(defenders);
  }

 

 

When we compare the two methods, we can see similar thing in this code, actually, in the code just has one difference: The condition to add in the list. There is the possibility that the next methods follow the same logic. So we'll refactor to use the same code, basically using a Filter interface.

 


public interface PlayerFilter {
  boolean filter(Player player);
} 

 

 

 

Now, the same code using the filter interface.

 


public List<Player> getForwarders() {
  return getFilteredPlayers(new PlayerFilter() {
@Override
  public boolean filter(Player player) {
return player.isFowarder();
  }
  });
  }

  public List<Player> getDefenders() {

  return getFilteredPlayers(new PlayerFilter() {
@Override
  public boolean filter(Player player) {
return player.isDefender();
  }
  });
  }

  private List<Player> getFilteredPlayers(PlayerFilter filter) {

  List<Player> filteredPlayers = new ArrayList<>();
  for (Player player : players) {
if(filter.filter(player)) {
filteredPlayers.add(player);
  }
  }
  return Collections.unmodifiableList(filteredPlayers);

  }

 

 

Just using lambda expressions, but not using Stream yet, we can make the code clearer.

 


    public List<Player> getForwarders() {
  return getFilteredPlayers(player -> player.isFowarder());
  }

  public List<Player> getDefenders() {
  return getFilteredPlayers(player -> player.isDefender());
  }

 

 

The code clearer, now using method reference:

 


   public List<Player> getForwarders() {
     return getFilteredPlayers(Player::isFowarder);
  }

  public List<Player> getDefenders() {
     return getFilteredPlayers(Player::isDefender);
  } 

 

 

But does anyone experienced this? The Stream API is a new data structure to work with stream in either sequential or parallel in an easier way.

 

Now, this time just using Stream, We can see how clear is our code using this new API, without make a new interface Filter.

 


  public List<Player> getForwarders() {
     return players.stream().filter(Player::isFowarder).collect(Collectors.toList());
  }

  public List<Player> getDefenders() {
     return players.stream().filter(Player::isDefender).collect(Collectors.toList());
  }

 

 

It's not good practice allow the client of the API modify the list, in other words, we should to return a read only list to the client. So, we can just add the “collectingAndThen” with the “Collections::unmodifiableList”.

 


    public List<Player> getForwarders() {

  return players.stream().filter(Player::isFowarder).collect(Collectors.
collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
  }

  public List<Player> getDefenders() {
  return players.stream().filter(Player::isDefender).collect(Collectors.
collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
  }

 

 

 

The result of the code using the newest API from Java 8.

 

 


public class Player {

  private String name;

  private int gols;

  private Position position;

  public Player(String name, int gols, Position position) {
  this.name = name;
  this.gols = gols;
this.position = position;
  }

  public String getName() {
  return name;
  }

  public int getGols() {
  return gols;
  }

  public Position getPosition() {
  return position;
  }


  public boolean isFowarder() {
  return FORWARDER.equals(position);
  }

  public boolean isDefender() {
  return DEFENDER.equals(position);
  }


} 

 


public class Team {

  private List<Player> players;

  public Team(List<Player> players) {
  this.players = players;
  }

  public List<Player> getForwarders() {

  return players.stream().filter(Player::isFowarder).collect(Collectors.
collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
  }

  public List<Player> getDefenders() {
  return players.stream().filter(Player::isDefender).collect(Collectors.
collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
  }


} 

 


public enum Position {
GOALKEEPER,DEFENDER, FORWARDS
} 

 


public class App
{
  public static void main( String[] args )
  {
  List<Player> players = new ArrayList<>();
players.add(new Player("Bobo", 10, Position.FORWARDER));
players.add(new Player("Zé Carlos", 8, Position.FORWARDER));
players.add(new Player("Lima", 4, Position.DEFENDER));
players.add(new Player("Lima", 14, Position.DEFENDER));
players.add(new Player("Ronaldo", 1, Position.GOALKEEPER));
  Team bahia = new Team(players);
  List<Player> defenders = bahia.getDefenders();
  List<Player> forwarders = bahia.getForwarders();
  }
}

 

 

 

 

Referência:


http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html

otaviojava

Money-API with Java EE

Posted by otaviojava Nov 29, 2015

The Java applications that use Java EE it is becoming more popular, This grow up happen mainly on 2009 after launched the Java EE 6 with CDI. A good benefits to use Java EE it's a Java specification, so there isn't locking vendor.

 

The Java EE is the most popular platform in the corporative world, these softwares have many goals. What they have in common is the fact represent money anyway. The monetary amount is really trivial in several systems such as finance applications, library, etc. However there was not a standard to work with money in Java. For many years many Java developers have been using primitives types from Java such as String, Long, Integer, etc. There are some problems when the developer use this solution like break the SOLID, lost encapsulation. So, now to solve this problem there is the JSR 354, the money-api, is a Java specification that was developed to many companies.

 

This article will use the current version of Java EE, the Java EE 7, and it will imagine a book store.

 

JPA

 

The Book model has three attributes.

 

  • Id
  • Name
  • value

 

@Entity 
public class Book implements Serializable { 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 

@Column 
private String name; 

@Column 
private MonetaryAmount value; 

//getter and setter 
    
}

A common problem in a custom type, such money, that the database cannot support this kind of information. A solution that became possible in JPA 2.1 is using converters. To create a converter is really simple, you just need to implement the AttributeConverter interface.

 

public class MonetaryAmountConveter implements  AttributeConverter { 

    private static final CurrencyUnit CURRENCY = Monetary.getCurrency("BRL"); 
    
    private static final MonetaryQuery EXTRACT_BIG_DECIMAL = (m) -> m.getNumber() 
            .numberValue(BigDecimal.class); 
            
    @Override 
    public BigDecimal convertToDatabaseColumn(MonetaryAmount attribute) { 
       return Optional.ofNullable(attribute).orElse(FastMoney 
               .zero(CURRENCY)) 
               .query(EXTRACT_BIG_DECIMAL); 
    } 

    @Override 
    public MonetaryAmount convertToEntityAttribute(BigDecimal dbData) { 
        return Money.of(dbData, CURRENCY); 
    } 
} 

 

The second step is define the converter in the field with Convert annotation.

 @Column
 @Convert(converter = MonetaryAmountConveter.class)
 private MonetaryAmount value;

 

In JPA 2.1 the converters work with just one field, so we have some options:

 

  • Save just number: In application just has one currency, it's possible, define a currency as constant. This way is possible do operations in the database as sum directly in the database, nevertheless if the project grow up the internationalization became a problem.
  • Save the number and currency as String: This strategy is enough the make the software to support many countries, notwithstanding it's hard to do database operations, so sum money just in a Java layer.
  • Save number and currency in different fields: Unfortunately it's not available in JPA 2.1, but you can use the Hibernate to do it, it's similar in JPA, implement an interface, the CompositeUserType. Now you can do database operations, however do operations in database there isn't guarantee if the currencies are equals and rounding operations, so can happen a mistake.

 

The Jadira is a framework that has several implementations to types in hibernate. Jadira has support to both JSR 310 and JSR 354.

 

CDI

 

It isn't nice to the Book entity be responsible to define the currency, it isn't its responsibility, break the SOLID. There are many strategies to create currency:

Create a currency from user locale.

Create a currency from tenant, for example, the serve “.com.br” the currency will be Brazilian real, “com.us” dollar.

Neither currency from user and currency from tenant is good option have the code spread in all the packages, to solve it there is CDI that work as glue in Java EE application.

 

public class MoneyProducer { 

    @Inject 
    private HttpServletRequest request; 

    @Produces 
    @RequestScoped 
    public CurrencyUnit getCurrency() { 
        return Monetary.getCurrency(request.getLocale()); 
    } 
} 
public class MoneyProducer { 

    @Inject 
    @Named("money_from_configurations") 
    private String money; 

    @Produces 
    @RequestScoped 
    public CurrencyUnit getCurrency() { 
        return Monetary.getCurrency(money); 
    } 
}

 

With the currency producer defined from CDI, we can inject “magically”. To it doesn't have several injection point to currency. A good idea is have a class specific to create money.

 

 

public class MonetaryAmountFactory { 

    @Inject 
    private CurrencyUnit currency; 
    
    
    public MonetaryAmount create(Number number) { 
        return Money.of(number, currency); 
    } 

} 

 

JAX-RS

 

Such as in JPA, JAX-RS there is a converter interface. Implement the interface ParamConverterProvider and annotated with @Provider. This interface has just one method and return the ParamConverter interface.

 

@Provider 
public class MonetaryAmountConverterProvider implements ParamConverterProvider { 


    @Override 
    public  ParamConverter getConverter(Class rawType, Type genericType, Annotation[] annotations) { 
        if (MonetaryAmount.class.isInstance(rawType)) { 
            return new ParamConverter() { 
                @Override 
                public T fromString(String value) { 
                    if(value == null || value.isEmpty()) { 
                        return null; 
                    } 
                    return rawType.cast(Money.parse(value)); 
                } 

                @Override 
                public String toString(T value) { 
                    if(value == null) { 
                        return null; 
                    } 
                    return value.toString(); 
                } 
            }; 
        } 
        return null; 
    } 
} 


@Provider 
public class CurrencyUnitConverterProvider implements ParamConverterProvider { 

    private CurrencyUnitParamConverter converter = new CurrencyUnitParamConverter(); 

    @Override 
    public  ParamConverter getConverter(Class rawType, Type genericType, Annotation[] annotations) { 
        if (CurrencyUnit.class.isInstance(rawType)) { 
            return new ParamConverter() { 
                @Override 
                public T fromString(String value) { 
                    if(value == null || value.isEmpty()) { 
                        return null; 
                    } 
                    return rawType.cast(Monetary.getCurrency(value)); 
                } 

                @Override 
                public String toString(T value) { 
                    if(value == null) { 
                        return null; 
                    } 
                    return value.toString(); 
                } 
            }; 
        } 
            return null; 
    } 
}

 

JSF

 

Interaction with the user is an important point in the applications, allow to an user read and write information is really important in several applications. The JSF is a specification to make it possible, such as other JSRs there is a converter to JSF.

 

@FacesConverter("money.midas.CurrencyConverter") 
public class CurrencyConverter implements Converter { 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, 
            String value) { 
         
        if (Objects.isNull(value)) { 
            return null; 
        } 
        return Monetary.getCurrency(value); 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, 
            Object value) { 
        if (Objects.isNull(value)) { 
            return null; 
        } 
        return value.toString(); 
    } 

} 

@FacesConverter("money.midas.MoneyConverter") 
public class MoneyConverter implements Converter { 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, 
            String value) { 
         
        if (Objects.isNull(value)) { 
            return null; 
        } 
        return Money.parse(value); 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, 
            Object value) { 
        if (Objects.isNull(value)) { 
            return null;
        } 
        return value.toString(); 
    } 
}

 

The Midas project

 

To do integrations between money-api with others frameworks, there is the Midas project. The goal of Midas is get support to:

  • JSF
  • Bean Validation
  • JPA
  • JAX-RS
  • CDI
  • Google Guice
  • Spring

 

In the midas, all converters of JSF, JPA, JAX-RS that was showed in this article is in midas. Beyond there is support to bean validation:

  • CurrencyAccepted: Define the currencies will be allowed in the either Currency and MonetaryAmount. You can inform either currency code or locale where the currency is from.
  • CurrencyRejected: Define the currencies will be rejected in the either Currency and MonetaryAmount. You can inform either currency code or locale where the currency is from.
  • MonetaryMax: Define the maximium value to the money.
  • MonetaryMin: Define the minimum value to the money.

 

    @CurrencyAccepted(currencies = "BRL") 
    private CurrencyUnit currencyUnit; 

    @CurrencyAccepted(currencies = "BRL") 
    @MonetaryMax("10.12") 
    private MonetaryAmount money;

 

References

Since begin of the time, the man need to do exchanges of goods materials or services, began with simples goods exchanges. In this time, already has necessity to start the standardization process, the first step was using metals as gold, silver and bronze becoming to representative money today. Nowadays with large number of e-commerce and automation of finance market and another systems that take care of money. The question frequently done is: How take care of this important measure unit? This article will talk about this point.

The first question is, witch variable use to represent the money? Integer, Long, Double, Float or BigDecimal? In Java Effective's book, told the problem to use floating representation, so we should avoid float and double and use BigDecimal, long or int.

public class Product { 
    private String name; 
    private BigDecimal price; 
    //getter and setter
}

Using BigDecimal, for example, we will have some problems, such show the value with monetary symbol, rounding, etc. So some developers make a MoneyUtils (a class with utilities of money), to help to do that. The problem will be spread and smell code. A good solution to solve this problem is create the Money's class, so centralize all money's behavior in just one object (show monetary symbol, etc.), this solutions look like more beautiful and has more OO aspect.

public class Product { 
    private String name; 
    private Money price;    
            //getter and setter 
}

But with a strong globalization and the buys from the Internet, is important worry to another monetary units, beyond your country, so born new challenges:

  • Find rates
  • Store currency to each country
  • Exchange rate
  • Understand the world standardization to currencies (ISO 4217)

With this goal was born the money API, JSR 354, to make easy the money's manipulation such rounding, exchange rate, etc.

Starting to talk about this API, the first step is create the currency unit, it is represented using the CurrencyUnit's interface, it's possible make a instance some forms as inform the currency code or using java.util.Locale of country of origin.

public class CreateCurrencyUnit 
{ 
    public static void main( String[] args ) 
    { 
        CurrencyUnit real = MonetaryCurrencies.getCurrency("BRL"); 
        CurrencyUnit dollar = MonetaryCurrencies.getCurrency(Locale.US); 
        System.out.println(real); //BRL

<p>Redis is a NOSQL database written in C. The Remote Dictionary Server is a key-value data base whose the storage is in memory, then the write and read will fastest way, but which difference between Redis and Cache? What does happen when the database fall down? Will we lost the all informations? The main goal of this article is talk about the Redis and show an open source project, the redis-collection.</p> <p> Analyzing cache tools such memcache and infinispan, also has this behavior with key-value, the first question that a Java developers does is: Which difference about Redis and cache?. To start, the serialization of the values, while the caches write in binary way, with Kryo or java.io.Serializable, in Redis everything is text or String. The problem in binary serialization is the impossibility of change the file manually or using another language. When Kryo or java.io.Serializable are used if change the object structure, you cannot retrieve the information with this structure, however write and read is faster than using text. There is a reason to it, caches are made to be faster but also temporary. Redis is a database and can storage this information, doing backup in hard driver, this way, if Redis fall down it can retrieves without lost all informations. Another dissemblance, in Redis there are another structures inside:</p> <br/> <li>String key and value</li> <li>List: are simply lists of strings, sorted by insertion order. It is possible to add elements to a Redis (similar in Java with java.util.List).</li> <li>Set: are an unordered collection of Strings constants with list you cannot put repetitive String (similar in Java with java.util.Set).</li> <li>Sorted Set: are, similarly to Redis Sets, non repeating collections of Strings. The difference is that every member of a Sorted Set is associated with score,</li> <li>Hashes: are maps between string fields and string values, so they are the perfect data type to represent objects (simillar in Java with Map<String, String>).</li> <br/> <p>Beyond there are more two, Bit arrays and HyperLogs, but will not mentioned in this article.</p> <p>After explain divergences between Redis and cache, next step will install the Redis that is very easy:</p> <br/> <ol> <li>Do the Download here: <a href="http://redis.io/" > http://redis.io/</a></li> <li> Uncompress and then compile the Redis: -> tar zxvf redis-version.x.tar.gz -> cd redis-version.x -> make </li> <li>Last step is run redis: cd src -> ./redis-server</li> </ol> <br/> <p>Done, Redis is running. To do some test, just execute the native client, just go to REDIS_HOME/src, next, run ./redis-cli.</p> <p>Feel free to run any commands, to know the commands in redis: <a href="http://redis.io/commands" >http://redis.io/commands</a></p> <p>After Redis ran and tested. Will used some data structures on Redis, some popular structures in Java: java.util.List, java.util.Set, java.util.Queue e java.util.Map, and more three: key-value as cache, counter and the last one to ranking.<p> <p>You can see the API here:</p> <br/> <pre class="brush:java"> public interface keyValueRedisStructure<T> { T get(String key); void set(String key, T bean); List<T> multiplesGet(Iterable<String> keys); void delete(String key); } public interface CountStructure<T extends Number> { T get(); T increment(); T increment(T count); T decrement(); T decrement(T count); void delete(); void expires(int ttlSeconds); void persist(); } public interface ListStructure <T> extends Expirable { List<T> get(String key); void delete(String key); } public interface MapStructure <T> extends Expirable{ Map<String, T> get(String key); void delete(String key); } public interface QueueStructure <T> extends Expirable { Queue<T> get(String key); void delete(String key); } public interface RankingStructure<T extends Number> extends Expirable { ScoresPoint<T> create(String key); void delete(String key); } </pre> <br/> <br/> <p>The idea of Expirable interface is define on key, the lifecycle, or time to expiry, of the objects in seconds, to remove this lifecycle just use the persist method. Remembering the Redis is in memory, but periodically the data are saved and all information are represented with String. In these structures was chose to serialize and deserialize the objects JSON, because is</p>

The new version of Easy-Cassandra, the version 2.0.1, have launched, some news are:

  • Refactoring constructor on Session Factory
  • QueryBuilder (InsertBuilder, UpdateBuilder, DeleteBuilder, SelectBuilder and BatchBuilder)
  • Go faster both write and read
  • Processo ]]>
  • More supports to Spring-Data

As have an easier the configuration a Session Factory, it was made the ClustInformation, this way do more configuration with less code.

 

 ClusterInformation clusterInformation = ClusterInformation.create() .addHost(HOST) .withDefaultKeySpace(KEY_SPACE).withUser(USER).withPassword(PASS); easyCassandraManager = new EasyCassandraManager(clusterInformation); 

 

This way the Spring Cassandra configuration has changed.

 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" <xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <context:component-scan base-package="org.easycassandra.persistence.cassandra.spring" /> <bean id = "clusterInformation" class="org.easycassandra.persistence.cassandra.ClusterInformation"> <property name="keySpace" value="campus" /> <property name="hosts"> <list> <value>localhost</value> </list> </property> </bean> <bean id="cassandraFactory" class="org.easycassandra.persistence.cassandra.spring.CassandraFactoryAnnotation"> <constructor-arg name="clusterInformation" ref="clusterInformation" /> <property name="annotatedClasses"> <list> <value>org.easycassandra.persistence.cassandra.spring.entity.Contact</value> <value>org.easycassandra.bean.model.Step</value> <value>org.easycassandra.bean.model.Weight</value> </list> </property> </bean> <bean id="cassandraTemplate" class="org.easycassandra.persistence.cassandra.spring.SimpleCassandraTemplateImpl" > <constructor-arg name="factory" ref="cassandraFactory" /> </bean> </beans> 

Configuration to Spring data on Easy-Cassandra

Maybe the most important improvement on this version is the QueryBuilder, the querybuilders are easy mode to do interaction with Cassandra, do more with less code, also was included BatchBuilder.

 

 SimpleID id = new SimpleID(); id.setIndex(ONE_HUNDRED_THIRTY); id.setKey(ONE_HUNDRED_THIRTY); UpdateBuilder update = template.updateBuilder(SimpleQueryBuilder.class, key); update.put("map", "name", "otavioMap").value("value", TEN_DOUBLE).execute(); 

Example of update

 UpdateBuilder update = persistence.updateBuilder(SimpleQueryBuilder.class); update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).addList("list", "otavioList").execute(); 
 UpdateBuilder update = persistence.updateBuilder(SimpleQueryBuilder.class); update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE).value("value", 12D).executeAsync(new ResultAsyncCallBack() { @Override public void result(Boolean bean) { // do some action } }); 

run an update asynchronously

 InsertBuilder insert= persistence.updateBuilder(SimpleQueryBuilder.class); Set set = new HashSet<>(); set.add("Linda"); Map map = new HashMap<>(); map.put("love", "Otavio and Poliana"); insert.value(Constant.KEY, Constant.ONE_HUNDRED).value(Constant.INDEX, Constant.ONE_HUNDRED).value(Constant.LIST_COLUMN, Arrays.asList("Poliana", "Otavio", "Love")) .value(Constant.SET_COLUMN, set).value("map", map).execute(); 

Do insert

 SimpleID id = new SimpleID(); id.setIndex(ONE_HUNDRED_TWO); id.setKey(ONE_HUNDRED_TWO); SimpleBean simpleBean = new SimpleBean(); simpleBean.setId(id); simpleBean.setValue(VALUE); InsertBuilder insert2 = persistence.updateBuilder(simpleBean); insert2.executeAsync((new ResultAsyncCallBack() { @Override public void result(Boolean bean) { // do some action } }); 

Do an insert asynchronously

 DeleteBuilder delete = persistence.deleteBuilder(SimpleQueryBuilder.class); delete.whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute(); DeleteBuilder delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class,"map", "list", "set"); delete2 .whereEq(Constant.INDEX, ONE_HUNDRED_TWO).whereEq(Constant.KEY, ONE_HUNDRED_TWO).execute(); 

The first query remove all columns from key and the second one will remove just the map, list and set columns.

 SimpleID id = new SimpleID(); id.setIndex(ONE_HUNDRED_TWO); id.setKey(ONE_HUNDRED_TWO); DeleteBuilder delete2 = persistence.deleteBuilder(SimpleQueryBuilder.class, id); delete2.executeAsync((new ResultAsyncCallBack() { @Override public void result(Boolean bean) { // do some action } }); 

Removing asynchronously.

 SelectBuilder select = persistence.selectBuilder(SimpleQueryBuilder.class); select.eq("name", "name"); select.in("index", ONE, TWO, THREE); List result = select.execute(); 

 

 SelectBuilder select = persistence.selectBuilder(SimpleQueryBuilder.class); select.eq(NAME, NAME).gt("index", THREE).asc(INDEX).executeAsync(new ResultAsyncCallBack>() { @Override public void result(List beans) { // do some thing } }); 

Run asynchronously the query.

The batch is a feature on Cassandra, that allow you execute modification on database (insert, update and remove) as one, this way you can send inserts, updates and deletes as on request.

 

 DeleteBuilder delete = dao.deleteBuilder(); delete.whereEq(Constant.INDEX, Constant.ONE_HUNDRED_TWO) .whereEq(Constant.KEY, Constant.ONE_HUNDRED_TWO); InsertBuilder insert = dao.insertBuilder(); insert.value(Constant.KEY, Constant.ONE_HUNDRED).value(Constant.INDEX, Constant.ONE_HUNDRED); insert.value(Constant.LIST_COLUMN, Arrays.asList("Poliana", "Otavio", "Love")); UpdateBuilder update = dao.update(); update.whereEq(Constant.KEY, Constant.ONE).whereEq(Constant.INDEX, Constant.ONE); update.addList("list", "otavioList"); BatchBuilder batchBuilder = dao.batchBuilder(); batchBuilder.addOperations(delete, insert, update); batchBuilder.executeAsync(new ResultAsyncCallBack() { @Override public void result(Boolean bean) { // do some action } }); 

Run the inserts, deletes, updates atomically with BatchBuilder.

This article talked about the new version of Easy-Cassandra and show new its features.

  1. https://github.com/otaviojava/Easy-Cassandra/wiki/Builders
  2. https://github.com/otaviojava/Easy-Cassandra/wiki
  3. https://github.com/otaviojava/Easy-Cassandra/
  4. https://github.com/otaviojava/Easy-Cassandra-samples

The Java is a platform which grown up quickly, for many rations such it can write once time and run anywhere, it runs languages on JVM. There is a myth that Java cannot compile its sources on run time, but it's truth?

Have a dynamic language is important to make some projects, for example, calculate taxes to different cities, so the source should be on the database and each city it puts the specific formula.

To show this functionality we will use a sample to solved the problem above, do change of formula on run time, to be easy and get focus on demonstration, we will use the four simple operations (add, multiply, subtract and divide) and to simulate the database, will have the txt file with Java's source inside. How cannot reference a class that was not created yet, we will make a interface to all classes on our