adam bien's blog

Generic CRUD Components with Java EE 5 📎

The mix of EJB 3, JPA and generics makes it possible to build lean and powerful management components with only few lines of code. Especially reusable CRUD components (e.g. masterdata management) do not have to be coded over and over again. The CRUD methods can be defined in a remote or local interface of a stateless session bean:

public interface CrudService<K,T> {
    public  T create(T t);
    public  T find(K id);
    public void delete(T t);
    public  T update(T t);
   //finders...
}
It is a plain interface without the @Remote annotation (a simple POJI).
The CRUD-logic is realized in a stateless session bean which provides the type of the primary key, as well as of the persistent entity:

@Stateless
@Remote(CrudService.class)
public class CrudServiceBean implements CrudService<Integer,Customer> {
   
    @PersistenceContext
    private EntityManager em;

    public Customer create(Customer t) {
        this.em.persist(t);
        return t;
   //remaining methods
    }

In this particular case, the interface is defined only once and realized by specific EJBs (which have to be implemented and deployed for each JPA-entity)
However a type-unsafe variation can be even more flexible.The usage of the java.io.Serializable (or Object), instead of a generic type allows the deployment of only one EJB, which is able then to manage all JPA-entities.

public interface GenericCrudService {
    public  Serializable create(Serializable t);
    public  Serializable find(Serializable id,Class type);
    public void delete(Serializable t);
    public  Serializable update(Serializable t);
    public Collection<Serializable> findByNamedQuery(String queryName);
    public Collection<Serializable> findByNamedQuery(String queryName,int resultLimit);
}

The implementation of the interface is straightforward:

@Stateless
@Remote(GenericCrudService.class)
public class GenericCrudServiceBean implements GenericCrudService {
  
    @PersistenceContext
    private EntityManager em;

    public Serializable create(Serializable t) {
        this.em.persist(t);
        return t;
    }

    @SuppressWarnings("unchecked")
    public Serializable find(Serializable id, Class type) {
       return (Serializable) this.em.find(type, id);
    }

    public void delete(Serializable t) {
       t = this.em.merge(t);
       this.em.remove(t);
    }

    public Serializable update(Serializable t) {
        return this.em.merge(t);
    }

    public Collection<Serializable> findByNamedQuery(String queryName) {
        return this.em.createNamedQuery(queryName).getResultList();
    }

    public Collection<Serializable> findByNamedQuery(String queryName, int resultLimit) {
        return this.em.createNamedQuery(queryName).setMaxResults(resultLimit).getResultList();
    }
EJB 3 are even efficient enough for the implementation of really simple use cases. This change a lot, comparing it to the J2EE/EJB 2.0 spec.
The whole example is available in p4j5.