我是Java Generics的新手。我正在设计我的DAO层。我正在使用JPA和Spring。我有一个BaseDAO,由所有其他DAO类扩展。
public abstract class BaseDAO<E, Id extends Serializable> implements IBaseDAO<E, Id> {
private Class<E> entityClass;
@PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
@SuppressWarnings("unchecked")
public BaseDAO() {
ParameterizedType genericSuperclass = (ParameterizedType) getClass()
.getGenericSuperclass();
this.entityClass = (Class<E>) genericSuperclass
.getActualTypeArguments()[0];
}
@Override
public E create(E entity) {
entityManager.persist(entity);
return entity;
}
//Some more methods
@Override
public List<?> executeNativeQuery(String queryString,
Map<String, Object> param) {
//implementation goes here
return resultList;
}
}
我在添加公共列表时遇到问题executeNativeQuery(String queryString, 映射param)到这个类。因为如果我在扩展BaseDAO的类A中使用此方法,我将必须为基类指定类型参数“E”和“Id”。理想情况下,type参数应该是我们要进行db调用的实体类。但由于此方法是本机查询方法,因此我不使用实体类。我该如何处理这种情况?
编辑: 假设下面是DAO类,它扩展了BaseDAO并使用了executeNativeQuery方法
公共类MyDAO扩展了BaseDAO {
public String myMethod(){
String query="select a1,a2,a3,b4 from A a, B b where a.pk=b.pk";
...
..
List<String> = executeNativeQuery(query, map, String.class);
...
..
}
}
如果我没有为BaseDAO指定类型参数,我仍会得到以下错误。
java.lang.Class无法在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)中强制转换为java.lang.reflect.ParameterizedType
应该为BaseDAO传递什么类型参数?
答案 0 :(得分:3)
您可以执行以下操作。
@Override
public <T> List<T> executeNativeQuery(String queryString,
Map<String, Object> param, Class<T> clazz) {
//implementation goes here
return resultList;
}
在第三个参数中,您可以指定要使用的列表的类型。 E. g。 List<SomeEntity> result = executeNativeQuery("query", paramMap, SomeEntity.class)
。
答案 1 :(得分:0)
正如我所看到的,问题出现在以下行的构造函数中。
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
您应该使用getGenericInterfaces()[0]
,因为BaseDAO
类不会从任何内容扩展(因此您获得Object
作为父级),但实现IBaseDAO
。