I've always needed to get concrete type from generic type at run time for many reasons, but this was not available in java.
Until now by using CDI in Java EE, I can inject one generic facade and use all CRUD operations needed for the entity concrete type at run time, with out the need of extension from AbstractFacade
as usually in-order to define class type.
Generic Facade:
@Transactional
public class Facade<T> {
@PersistenceContext(unitName = "PU")
protected EntityManager em;
private Class<T> entityClass;
public Facade(Class<T> entityClass) {
this.entityClass = entityClass;
}
public Facade() {
}
@Inject
public Facade(InjectionPoint ip) {
try {
Type t = ip.getType();
Field f = t.getClass().getDeclaredField("actualTypeArguments");
f.setAccessible(true);
Type[] ts = ((Type[]) f.get(t));
this.entityClass = (Class<T>) ts[0];
} catch (Exception e) {
e.printStackTrace();
}
}
public T save(T entity) {
return getEntityManager().merge(entity);
}
public void delete(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
@SuppressWarnings("rawtypes")
CriteriaQuery cq = getEntityManager().getCriteriaBuilder()
.createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
...
Then by using @Inject:
@Inject
Facade<Person> personFacade;
@Inject
Facade<OtherType> otherTypeFacade;
...
Every thing worked fine, and concrete type is read at runtime.The question is
If there is no need for custom queries or business on specific types,can this solution be an alternative for AbstractFacade
which needs to be extended?