Developing applications with MongoDB and PrimeFaces on WildFly

User Rating: 3 / 5

Star ActiveStar ActiveStar ActiveStar InactiveStar Inactive
 

This tutorial shows how to build an application which exports/imports data contained in a PrimFaces datatable in MongoDB

MongoDB is a popular noSQL database which can be freely obtained from: http://www.mongodb.org/downloads
Once downloaded, create a script named for example startmongodb.cmd (or equivalent for Linux) which starts the Mongo database, selecting a location for the storage:

mongod --dbpath=C:\MongoDB2.6\data


Now execute the above script and check that it started accepting connections:

2014-08-20T22:21:37.453+0200 [initandlisten] MongoDB starting : pid=6440 port=27017 dbpath=C:\MongoDB2.6\data 64-bit host=francesco-PC
2014-08-20T22:21:37.455+0200 [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2014-08-20T22:21:37.455+0200 [initandlisten] db version v2.6.4
2014-08-20T22:21:37.455+0200 [initandlisten] git version: 3a830be0eb92d772aa855ebb711ac91d658ee910
2014-08-20T22:21:37.455+0200 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1')BOOST_LIB_VERSION=1_49
2014-08-20T22:21:37.455+0200 [initandlisten] allocator: system
2014-08-20T22:21:37.455+0200 [initandlisten] options: { storage: { dbPath: "C:\MongoDB2.6\data" } }
2014-08-20T22:21:37.470+0200 [initandlisten] journal dir=C:\MongoDB2.6\data\journal
2014-08-20T22:21:37.471+0200 [initandlisten] recover : no journal files present no recovery needed
2014-08-20T22:21:37.574+0200 [initandlisten] waiting for connections on port 27017


As MongoDB client we will download MongoVue which is available at: http://www.mongovue.com/downloads/
Download it, then install it and execute it (Select to use the Community version at startup). Our initial task will be to connect to the MongoDB using an anonymous connection as follows:
mongodb wildfly jboss tutorial
Next, create a new database named wildflyschema:
mongodb wildfly jboss tutorial
Done with the database, we will now engineer a simple JSF application enriched by PrimeFaces. This is the Model CDI bean which does most of the Job, that is saving Data in MongoDB (using the saveMongo method) and load data from MongoDB using the loadMongo method.


@Model
public class CarManager {
    List<Car> carList = new ArrayList();
    @Inject
    MongoClient mongoClient;

    @PostConstruct
    public void init() {
        Car car1 = new Car("F40", new Date(), "Ferrari", "Red");
        Car car2 = new Car("Huracan", new Date(), "Lamborghini", "Green");
        Car car3 = new Car("Cayenne", new Date(), "Porsche", "Black");
        carList.add(car1);
        carList.add(car2);
        carList.add(car3);
    }

    public void loadMongo() {

        DB db = mongoClient.getDB("wildflyschema");

        DBCollection table = db.getCollection("cars");

        BasicDBObject searchQuery = new BasicDBObject();
        searchQuery.put("manufacturer", "Ferrari");

        DBCursor cursor = table.find();

        while (cursor.hasNext()) {
            BasicDBObject document = (BasicDBObject) cursor.next();
            Car car = new Car((String) document.get("model"),
                    (Date) document.get("date"),
                    (String) document.get("manufacturer"),
                    (String) document.get("color"));

             carList.add(car);
        }

    }

    public void clear() {
        carList.clear();
    }

    public void saveMongo() {

        DB db = mongoClient.getDB("wildflyschema");

        DBCollection table = db.getCollection("cars");

        for (Car car : carList) {
            BasicDBObject document = new BasicDBObject();
            document.put("color", car.getColor());
            document.put("date", car.getDate());
            document.put("manufacturer", car.getManufacturer());
            document.put("model", car.getModel());
            table.insert(document);
        }

        System.out.println("Done!");

    }

    public List getCarList() {
        return carList;
    }

    public void setCarList(List carList) {
        this.carList = carList;
    }

}


The objects that will be manipulated in this Bean, are Car objects which are statically created in the init() method of the Bean. In the following tutorial I'll add CRUD capabilities to the Datatable List (contained in carList) so that you can add,delete or modify the content of the datatable.

As you can see, the CarManager gets injected the MongoClient so obviously there is a CDI Producer in this application which follows here:

@ApplicationScoped
public class MongoProducer {
    MongoClient mongoClient;
     @Produces
        public MongoClient create() {
            try {
                mongoClient = new MongoClient();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            return mongoClient; 
        }

        public void close(@Disposes final MongoClient mongoClient) {
            mongoClient.close();
        }
}


The MongoProducer class creates thread-safe instances of MongoClient which are then finalized in the close method that contains a @Disposes annotation.
For the sake of completeness, we will include also the Car class which is a POJO:

public class Car {
    private String model;
    private Date date;
    private String manufacturer;
    private String color;
    
    public Car(String model, Date date, String manufacturer, String color) {
            this.model = model;
            this.date = date;
            this.manufacturer = manufacturer;
            this.color = color;
    }
    // Getters-Setters here
}


Now, the UserInterface which is a generic index.xhtml page containing a Datatable engineered with PrimeFaces components:

<!DOCTYPE html>
<html xmlns="http://www.w3c.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
    <h:form id="jsfexample">


        <p:panelGrid columns="2">
            <f:facet name="header">Cars Availabke</f:facet>

            <p:dataTable id="table" var="car" value="#{carManager.carList}">
                <p:column headerText="Model">
                    <h:outputText value="#{car.model}" />
                </p:column>

                <p:column headerText="Year">
                    <h:outputText value="#{car.date}" />
                </p:column>

                <p:column headerText="Manufacturer">
                    <h:outputText value="#{car.manufacturer}" />
                </p:column>

                <p:column headerText="Color">
                    <h:outputText value="#{car.color}" />
                </p:column>
            </p:dataTable>
            <f:facet name="footer">

                <p:commandButton action="#{carManager.saveMongo}" value="Save" />
                <p:commandButton action="#{carManager.clear}" value="Clear"
                    update="table" />
                <p:commandButton action="#{carManager.loadMongo}" value="Load"
                    update="table" />
            </f:facet>
        </p:panelGrid>

    </h:form>
</h:body>
</html>    


As you can see, besides the Load and Save button, I've added a Clear button which empties the list of cars so that we can get it back from MongoDB.
In order to compile and deploy the application, you can use the following pom.xml which contains a dependency to the CDI API, the JSF and PrimeFaces API and, of course, MongoDB Java driver:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sample</groupId>
    <artifactId>DemoMongoDB</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>

    <name>HelloPrime</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.wildfly.bom</groupId>
                <artifactId>jboss-javaee-7.0-with-all</artifactId>
                <version>8.0.0.Final</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>2.10.1</version>
        </dependency>

        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.spec.javax.faces</groupId>
            <artifactId>jboss-jsf-api_2.2_spec</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>5.0</version>
        </dependency>

    </dependencies>
    <build>

        <finalName>${project.artifactId}</finalName>

        <plugins>

            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>1.0.0.Final</version>
            </plugin>
        </plugins>
    </build>
</project>

Installing MongoDB as a module on WildFly

As it is, the application bundles MongoDB JAR file (mongo-2.10.1.jar) into the WEB-INF/lib folder of your application. If you prefer, you can choose to install it on the application Server as a Module using the following CLI:

module add --name=org.mongodb --resources=C:\MongoDB2.6\mongo-2.10.1.jar 
--dependencies=javax.api,javax.transaction.api

Next, include in your Manifest file (or jboss-deployment-structure.xml) a Dependency on the module. For example:

Dependencies: org.mongodb

Finally, declare the dependency as provided in your pom.xml so it will not be bundled in the web application:

<dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>2.10.1</version>
            <scope>provided</scope>
</dependency>

So whatever is your choice (to install it as module or not), you can deploy the application as usual with:

mvn wildfly:deploy

Now check the basic use case: Save the data on MongoDB, Clear the table, Load back the data from MongoDB.
You should see again your Datatable populated!

mongodb tutorial wildfly jboss
From MongoVUE you can inspect the content of wildflyschema and verify the list of documents contained in it:

mongodb tutorial wildfly jboss


Advertisement