由于种种原因,我总是需要在运行时从泛型类型中获取具体类型,但这在java中不可用。
到目前为止,通过在Java EE中使用CDI,我可以注入一个通用的Facade,并在运行时使用实体具体类型所需的所有CRUD操作,而不需要AbstractFacade
的扩展,通常按顺序定义类类型。
通用立面:
@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();
}
...
然后使用@Inject:
@Inject
Facade<Person> personFacade;
@Inject
Facade<OtherType> otherTypeFacade;
...
每件事都运行良好,并且在运行时读取具体类型。问题是
如果不需要针对特定类型的自定义查询或业务,此解决方案是否可以替代需要扩展的AbstractFacade
?