Making persistence layer (Starting with facelets part 2)
This is the second part of Starting with Facelets tutorial. To make Blog app working we have to deal with persistence. I’ll use Hibernate for persistence mechanism (it’s integrated with JBoss platform so you don’t need to download additional jars and add them to project). In the first part I have created JSF project in Eclipse and now I am going to create Enterprise app and EJB Project (for ejb beans and entities) in Eclipse and place existing web application in it. When create Enterprice application you have to add DemoFacelets project (web app from the first part) and ejb project which is created in this part of tutorial. The reason why I’m doing this, cause I’m gonna use EJB and all functionality of JBoss AS for deploying Java enterprise apps.
First, we have to make entity classes. This is a simple blog app and there are only 3 entities. It’s User, Article and Comment. Logic is very simple. User (Author) writes blog articles and others comment on it. Go to New–New EJB Project to create EJB project in Eclipse. After this create Enterprice application. Create package demo.model and place following code for Article Java class.
package demo.model;
import static javax.persistence.GenerationType.IDENTITY;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
@Entity
public class Article implements Serializable{
private static final long serialVersionUID = 4902391506140773812L;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "_id", unique = true, nullable = false)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id", nullable = false)
private User author;
private Date dateOfPublishing;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "article")
private List<Comment> comments;
private int rating;
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setAuthor(User author) {
this.author = author;
}
public User getAuthor() {
return author;
}
public void setDateOfPublishing(Date dateOfPublishing) {
this.dateOfPublishing = dateOfPublishing;
}
public Date getDateOfPublishing() {
return dateOfPublishing;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getRating() {
return rating;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public List<Comment> getComments() {
return comments;
}
}
For managing relations between entities I’ve used Java persistence annotations. The relation between Article and Comment is parent/children relationship. To implement this kind of relation I’ve used bidirectional mapping. Relationship with Article class in Comment class is mapped with ManyToOne annotation.
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "author_id", nullable = false) private User author;
There are also User and Comment classes which are also annotated but it is trivial. You can download all 3 classes.
Generic DAO pattern
There are several patterns how to implement persistence layer. For me the most elegant solution is to use Generic DAO pattern which makes following benefits:
- Reusing non-CRUD operation. With generic DAO pattern you provide higher level of abstraction for data access operations instead basic CRUD operations
- Persistence layer have generic interface without exposing implementation. You can implement it in Hibernate or JPA. One interface (facade) is always exposed.
There are 2 hierarchies. On one side is interfaces and on the other is its implementations. The highest interface defines basic operations(Create,Read,Update,Delete). The sub interfaces is defined for each entity in application that requires operations with database. The same logic is with implementation classes.
GenericDao interface have basic CRUD operations. All interfaces are in demo.persistence package. Also I have used Java generics. T parameter is the entity for which I’m implementing DAO.
package demo.persistence;
import java.util.List;
public interface GenericDAO<T> {
void save(T object);
T get(Long id);
void update(T object);
void delete(T object);
List<T> listAll();
}
For DAO implementations I have used EJB 3.0. All DAO objects are implemented as stateless EJB beans. GenericDAOImpl is abstract class and it isn’t EJB bean. It has references to hibernate session and implemented basic and common operations (CRUD). All DAO implementation classes are subclass of GenericDAOImpl abstract class and EJB stateless beans.
package demo.persistence.implementation;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import javax.persistence.PersistenceContext;
import demo.persistence.GenericDAO;
public abstract class GenericDAOImpl<T> implements GenericDAO<T> {
@PersistenceContext(unitName="BlogPU")
private Session session;
private Class<T> persistentClass;
@SuppressWarnings("unchecked")
public T get(Long id) {
Criteria criteria = session.createCriteria(getPersistentClass()).
add(Restrictions.like("id", id));
T uniqueResult = (T) criteria.uniqueResult();
return uniqueResult;
}
@SuppressWarnings("unchecked")
public List<T> listAll() {
Criteria criteria = session.createCriteria(getPersistentClass());
return criteria.list();
}
public void save(T object) {
session.saveOrUpdate(object);
}
public void update(T object) {
session.update(object);
}
public void delete(T object) {
session.delete(object);
}
public void setSession(Session session) {
this.session = session;
}
public Session getSession() {
return session;
}
public void setPersistentClass(Class<T> persistentClass) {
this.persistentClass = persistentClass;
}
public Class<T> getPersistentClass() {
return persistentClass;
}
}
With anotaion @PersistenceContext(unitName=”BlogPU”) hiberante session is injected with persistence unit BlogPU which is defined in persistence.xml file (I’ll explain content of this file later)
Adding configuration files
We have persistence layer implemented using DAO pattern but I did not configure data source. The moste easiest way to configure data source on JBosss AS is to make it as default data source. Make new file mysql-ds.xml and add following xml:
<?xml version="1.0" encoding="UTF-8"?> <datasources> <local-tx-datasource> <jndi-name>BlogAppDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/BlogAppDS</connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <!-- enter your username and password for MySQL server --> <user-name>YOURUSERNAME</user-name> <password>YOURPASSWORD</password> <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name> <metadata> <type-mapping>mySQL</type-mapping> </metadata> </local-tx-datasource> </datasources>
You have to add url of database (<connection-url> tag),jndi name, mysql jdbc driver (<com.mysql,jdbc.Driver> tag), username and password. Place file in /%jboss-5.1.0.GA install. dir. %/server/default/deploy To make all work download mysql driver jar and place it in %jboss-5.1.0.GA install. dir. %/server/default/lib folder.
Maybe this post isn’t straitforward. Maybe it is confusing. Dear reader, all these technologies aren’t straitforward and it is take time to learn and use it on right way. Good luck!!

Trackbacks & Pingbacks