我正在尝试设置一个泛型类,它将作为我的应用程序中所有Dao类的基类,但我现在面临一个错误。我的泛型类是这样定义的;
public class Dao<E> {
private final E entity;
@Autowired
SessionFactory sessionFactory;
protected Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
public Dao(E entity) {
this.entity = entity;
}
public E getEntity() {
return this.entity;
}
@Transactional
public boolean persist(E transientInstance) {
try {
sessionFactory.getCurrentSession().persist(transientInstance);
return true;
} catch (RuntimeException re) {
return false;
}
}
@Transactional
public boolean remove(E transientInstance) {
try {
sessionFactory.getCurrentSession().delete(transientInstance);
return true;
} catch (RuntimeException re) {
return false;
}
}
@SuppressWarnings("unchecked")
@Transactional
public E merge(E detachedInstance) {
try {
E result = (E) sessionFactory.getCurrentSession().merge(detachedInstance);
return result;
} catch (RuntimeException re) {
return null;
}
}
@Transactional
public E findById(int id) {
try {
E instance = (E) sessionFactory.getCurrentSession().get(E, id);
return instance;
} catch (RuntimeException re) {
return null;
}
}
@SuppressWarnings("unchecked")
@Transactional
public E findByUsername(String username) {
try {
E instance = (E) sessionFactory.getCurrentSession().createCriteria(E, username).add(Restrictions.like("login", username)).list().get(0);
return instance;
} catch (RuntimeException re) {
return null;
}
}
@SuppressWarnings("unchecked")
@Transactional
public List<E> findAll() {
try {
List<E> instance = sessionFactory.getCurrentSession().createCriteria(E).list();
return instance;
} catch (RuntimeException re) {
return null;
}
}
}
有错误的方法是最后三个,而与get()和createCriteria()对它们的引用有关(错误是 E不能是解决了变量)。通常,我会使用像Usuario.class&#39;当我不使用这种基于通用的方法时。
任何人都知道如何在我的泛型类中修复此错误(如果这种方法甚至可行)。
答案 0 :(得分:1)
首先,类型参数E
不等于Class
的实例。其次,由于Java中的类型擦除,E的所有内容都在运行时丢失。但是entity
作为参数传递给构造函数的接缝是在尝试请求类时使用的类型标记。因此,改变方法如下:
@Transactional
public E findById(int id) {
try {
E instance = (E) sessionFactory.getCurrentSession().get(entity.getClass(), id);
return instance;
} catch (RuntimeException re) {
return null;
}
}
@SuppressWarnings("unchecked")
@Transactional
public E findByUsername(String username) {
try {
E instance = (E) sessionFactory.getCurrentSession().createCriteria(entity.getClass(), username).add(Restrictions.like("login", username)).list().get(0);
return instance;
} catch (RuntimeException re) {
return null;
}
}
@SuppressWarnings("unchecked")
@Transactional
public List<E> findAll() {
try {
List<E> instance = sessionFactory.getCurrentSession().createCriteria(entity.getClass()).list();
return instance;
} catch (RuntimeException re) {
return null;
}
}
或如果entity
不是您的类型令牌,请将参数Class<E> clazz
添加到构造函数中,如下所示:
private final E entity;
private final Class<E> clazz;
public Dao(E entity, Class<E> clazz) {
this.entity = entity;
this.clazz = clazz;
}
并在我建议的方法中使用clazz
代替entity.getClass()
。
答案 1 :(得分:0)
只需添加上面的答案。如果您不想将参数传递给构造函数,可以执行以下操作:
private Class<T> type;
public Dao(){
Type t = getClass().getGenericSuperclass();
ParameterizedType pt = (ParameterizedType) t;
type = (Class<T>) pt.getActualTypeArguments()[0];
}
然后在您进行查询时在您的条件中引用类型。
附录:从您的DAO图层中移除@Transactional
注释,@Transactional
属于您的服务层