JPA Generic Repo
This is a generic repo for JPA entities that have an auto generated "id" column
Usage
Create JPA entities that extend IdEntity and have an auto generated id
@Entity
public class Person extends IdEntity
{
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
private String name;
Create repo beans that extend Repo class
@Named("personRepo") @ApplicationScoped
public class PersonRepo extends Repo<Person> implements Serializable
{
public PersonRepo()
{
super(Person.class);
}
public ArrayList<Person> search(String needle) throws Exception
{
ArrayList<Person> list = new ArrayList<>();
if(needle == null || needle.isEmpty())
return list;
try
{
String sql = "SELECT x FROM Person x WHERE x.name = :needle";
Query q = this.getEntityManager().createQuery(sql);
list.addAll(q.getResultList());
}
catch(NoResultException nre)
{
return list;
}
catch(Exception e)
{
throw e;
}
return list;
}
This would be an example of usage
@Inject private PersonRepo personRepo;
...
Person person = new Person();
//person has no id
person.setName("John");
person = personRepo.create(person);
//person should now have an id
person.setName("John Doe");
personRepo.update(person);
Files
IdEntity.java
import java.io.Serializable;
public abstract class IdEntity implements Serializable
{
public abstract Integer getId();
}
Repo.java
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Repo<T extends IdEntity> implements Serializable
{
@Resource(lookup="java:jboss/UserTransaction")
private UserTransaction tx;
@PersistenceContext(unitName = "UNIT_NAME_HERE")
private EntityManager em;
@Resource(lookup="java:jboss/datasources/DATASOURCE_NAME_HERE")
private DataSource dataSource;
private Class<T> type;
public Repo(Class<T> type)
{
this.type = type;
}
/**
* GET ENTITY MANAGER
*/
public EntityManager getEntityManager()
{
return em;
}
/**
* TRANSACTIONS
*/
private void beginTransaction() throws Exception
{
try {
tx.begin();
}
catch (Exception e) {
rollBackTransaction();
throw e;
}
}
private void commitTransaction() throws Exception
{
try {
tx.commit();
} catch (Exception e) {
rollBackTransaction();
throw e;
}
}
private void rollBackTransaction() throws SystemException
{
try {
if(tx != null)
tx.rollback();
} catch (Exception e) {
throw e;
}
}
/**
* CRUDL
*/
public T create(T obj) throws Exception
{
beginTransaction();
em.persist(obj);
em.flush();
commitTransaction();
if(obj.getId() == null)
{
throw new Exception("CHECK FOR @GeneratedValue(strategy=GenerationType.IDENTITY) ON " + obj.getClass().getSimpleName() + "ENTITY");
}
else
{
return obj;
}
}
public T read(Integer id)
{
T obj = null;
obj = em.find(type, id);
return obj;
}
public Boolean update(T obj) throws Exception
{
beginTransaction();
em.merge(obj);
commitTransaction();
return true;
}
public Boolean delete(T obj) throws Exception
{
T x = em.find(type, obj.getId());
beginTransaction();
em.remove(em.merge(x));
commitTransaction();
return true;
}
public List<T> list()
{
return filter(0,0,"id", "A", null);
}
/**
* FILTER
*/
public List<T> filter(int start, int limit, String sortField, String sortOrder, Map<String, String> filters)
{
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<T> query = builder.createQuery(type);
Root<T> root = query.from(type);
query.select(root);
Path<T> path = (sortField == null || sortField.isEmpty()) ? root.get("id") : root.get(sortField);
if(sortOrder != null && sortOrder.toLowerCase().startsWith("d"))
query.orderBy(builder.desc(path));
else
query.orderBy(builder.asc(path));
/**
* FILTERING
*/
if(filters != null)
{
Predicate filterCondition = builder.conjunction();
for(Map.Entry<String, String> filter : filters.entrySet())
{
if(! filter.getValue().equals(""))
{
String field = filter.getKey();
String value = filter.getValue();
Path<String> pathFilter = root.get(field);
if(pathFilter != null)
{
if(value.equals("true") || value.equals("false"))
{
filterCondition = builder.and(filterCondition, builder.equal(pathFilter, (value.equals("true"))));
}
else
filterCondition = builder.and(filterCondition, builder.like(pathFilter, "" + value + ""));
}
}
}
query.where(filterCondition);
}
/**
* PAGINATION
*/
TypedQuery<T> tq = em.createQuery(query);
if(limit > 0)
tq.setMaxResults(limit);
if(start > 0)
tq.setFirstResult(start);
List<T> list = new ArrayList<>();
list.addAll(tq.getResultList());
return list;
}
/**
* NATIVE QUERY
*/
public List nativeQuery(String sql)
{
ArrayList list = new ArrayList<>();
Query q = em.createNativeQuery(sql, type);
list.addAll(q.getResultList());
return list;
}
}