The last time I developed an app using JBoss 7.1 (Java EE6 standard), I wrote the persistence layer using DAOs.
First of all, I had an "abstract" DAO which was the father of all concrete daos:
public abstract class AbstractDao<T> {
private Class<T> entityClass;
private String defaultSortColumn;
public AbstractDao(Class<T> entityClass) {
this.entityClass = entityClass;
this.defaultSortColumn = "";
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
@SuppressWarnings("rawtypes")
public List<T> find() {
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root from = cq.from(entityClass);
cq.select(from);
return getEntityManager().createQuery(cq).getResultList();
}
@SuppressWarnings("rawtypes")
public int count() {
//...
}
}
Then I have one dao implementation for each DB entity in my domain.
They're all really similar to each other, they simply add methods for queries more complex than usual "crud" operations.
Here's one example:
@Stateless
public class ShopDao extends AbstractDao<Shop> {
@Inject
private EntityManager em;
@Override
protected EntityManager getEntityManager() {
return em;
}
public ShopDao() {
super(Shop.class);
}
}
As you can see my DAOs are stateless EJBs.
This way makes my app work but... when I have to create a new entity, I have to create both the entity itself and the DAO. A bit redundant isn't it? However, I can't imagine a better way, because I often need to have complex queries for specific entities.
Questions are:
is this the best practice? How else can I design my persistence layer?
is it good for a DAO to be a EJB?
I have validation in the client side (JSF controllers). Should it be in the persistence layer? How?
would it be better to have the raw EntityManager in a Service layer class, avoiding DAOs?
EDIT
Is there a way to avoid having one dao for each table?
"is this the best practice? How else can I design my persistence layer?"
Your approach seems ok. Some people prefer to have DAO layer totally independent on other layers. The advantage of such approach is that you can reuse DAO layer elsewhere and it is also easier to test your DAOs outside application server. I am not big advocate of such approach since very often it is an overkill - EJB methods are just thin wrappers around DAO layer. EJBs are also easy to test outside application server (Spring provides all needed testing facilities). So, as long as you are not planning to implement in your EJB more complicated bussiness logic, I would go with your approach.
Read on for more details...
"is it good for a DAO to be a EJB?"
To be more precise, EJBs are not DAOs in your approach, since they also manage transactions, can be responsible for other, non database, elements of bussiness logic. EJBs also provide external interface to your application. Technically speaking, EntityManager is your DAO and EJBs are using it to implement all needed bussiness logic.
"I have validation in the client side (JSF controllers). Should it be in the persistence layer? How?"
In Java EE 6 you can take advantage of Bean Validation technology - you define your validation rules at the model level (as annotations on entities' fields) and these rules are enforced both by persistence layer and JSF web layer.
"would it be better to have the raw EntityManager in a Service layer class, avoiding DAOs?"
As I understand you want to get rid of EJBs? You can do that, but then you'll need to manage transactions by yourself (not a big deal in simple cases). Stateless local interface or no interface EJBs are pretty lightweight right now, so there is no good reason to avoid them. As a replacemen you can use Spring Framework support for JPA.