首页 > 代码库 > 利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)
利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)
想利用泛型抽取BaseDao层,简化操作时出现问题:
@Transactional这个注解是可以继承的,于是就想写在抽取的BaseDao层上,让实现的类可以不用写@Transactional,就可开启事务。
问题描述:
由于偷懒,没给BaseDao抽接口,代码如下:
package com.liang.ssh2.base; import java.lang.reflect.ParameterizedType; import java.util.Collections; import java.util.List; import javax.annotation.Resource; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Transactional; import com.liang.ssh2.config.Configuration; import com.liang.ssh2.entity.Page; import com.liang.ssh2.util.QueryHelper; @Transactional @SuppressWarnings("unchecked") public class BaseDao<T>{ @Resource private SessionFactory sessionFactory; Class <T> clazz; /** * 通过反射获取参数类型 */ public BaseDaoImpl(){ System.out.println(this); ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); clazz=(Class<T>) pt.getActualTypeArguments()[0]; } /** * 获取当前可用的Session * @return */ protected Session getSession() { return sessionFactory.getCurrentSession(); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#save(T) */ public void save(T entity){ getSession().save(entity); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#getById(java.lang.Long) */ public T getById(Long id){ if(id==null) return null; return (T) getSession().get(clazz, id); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#update(T) */ public void update(T entity){ getSession().update(entity); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#delete(java.lang.Long) */ public void delete(Long id){ if(id!=null){ Object entity=getById(id); if(entity!=null){ getSession().delete(entity); } } } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#getByIds(java.lang.Long[]) */ public List<T> getByIds(Long[] ids){ if(ids==null||ids.length==0){ return Collections.EMPTY_LIST; } return getSession().createQuery(// "from "+clazz.getSimpleName()+"where id in(:ids)")// .setParameterList("ids", ids)// .list(); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#findAll() */ public List<T> findAll(){ return getSession().createQuery(// "from "+clazz.getSimpleName())// .list(); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#getPage(long, java.lang.Long, com.liang.ssh2.util.QueryHelper) */ public Page getPage(long currentPage,Long pageSize,QueryHelper queryHelper){ //如果用户没有动态指定pageSize,则读取配置文件 if(pageSize==null){ pageSize=Configuration.getPageSize(); } //获得参数 List<Object> parameters = queryHelper.getParameters(); Query query = getSession().createQuery(queryHelper.getQueryListHql()); if(parameters!=null&¶meters.size()>0){ for (int i = 0; i < parameters.size(); i++) { query.setParameter(i, parameters.get(i)); } } query.setFirstResult((int) ((currentPage-1)*pageSize)); query.setMaxResults(pageSize.intValue()); List recordList = query.list(); // 查询总记录数 query = getSession().createQuery(queryHelper.getQueryCountHql()); // 注意空格! if (parameters != null && parameters.size() > 0) { // 设置参数 for (int i = 0; i < parameters.size(); i++) { query.setParameter(i, parameters.get(i)); } } Long recordCount = (Long) query.uniqueResult(); // 查询 return new Page(currentPage, pageSize, recordCount, recordList); } }
使用如下:
package com.liang.ssh2.service.impl; import org.springframework.stereotype.Service; import com.liang.ssh2.base.BaseDao; import com.liang.ssh2.entity.User; @Service public class UserServiceImpl extends BaseDao<User>{ }
注意我是把@Transactional放在BaseDao上了,由于@Transactional可继承,所以UserServiceImpl是不用放的
当启动服务器时会报错:Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
为什么会这样呢?
测试了半天发现,出错就在BaseDao上注解:@Transactional上,原因不是很清楚!!!
两种解决方案:
一、直接将BaseDao上的@Transactional注解去掉,在实现类上加@Transactional,对于本例,在UserServiceImpl加上@Transactional即可开启事务,也不会报错!
二、别偷懒了,乖乖的给BaseDao抽个接口吧,其他什么都不用改,@Transactional还是照样可以继承,修改代码如下:
package com.liang.ssh2.base; import java.util.List; import com.liang.ssh2.entity.Page; import com.liang.ssh2.util.QueryHelper; public interface BaseDao<T> { /** * 保存实体 * @param entity */ public abstract void save(T entity); /** * 根据id获取实体 * @param id * @return */ public abstract T getById(Long id); public abstract void update(T entity); public abstract void delete(Long id); public abstract List<T> getByIds(Long[] ids); public abstract List<T> findAll(); /** * 获取page * @param currentPage * @param pageSize //如果用户没有动态指定pageSize(null),则读取配置文件 * @param queryHelper * @return */ public abstract Page getPage(long currentPage, Long pageSize, QueryHelper queryHelper); }
package com.liang.ssh2.base; import java.lang.reflect.ParameterizedType; import java.util.Collections; import java.util.List; import javax.annotation.Resource; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Transactional; import com.liang.ssh2.config.Configuration; import com.liang.ssh2.entity.Page; import com.liang.ssh2.util.QueryHelper; @Transactional @SuppressWarnings("unchecked") public class BaseDaoImpl<T> implements BaseDao<T>{ @Resource private SessionFactory sessionFactory; Class <T> clazz; /** * 通过反射获取参数类型 */ public BaseDaoImpl(){ System.out.println(this); ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); clazz=(Class<T>) pt.getActualTypeArguments()[0]; } /** * 获取当前可用的Session * @return */ protected Session getSession() { return sessionFactory.getCurrentSession(); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#save(T) */ public void save(T entity){ getSession().save(entity); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#getById(java.lang.Long) */ public T getById(Long id){ if(id==null) return null; return (T) getSession().get(clazz, id); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#update(T) */ public void update(T entity){ getSession().update(entity); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#delete(java.lang.Long) */ public void delete(Long id){ if(id!=null){ Object entity=getById(id); if(entity!=null){ getSession().delete(entity); } } } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#getByIds(java.lang.Long[]) */ public List<T> getByIds(Long[] ids){ if(ids==null||ids.length==0){ return Collections.EMPTY_LIST; } return getSession().createQuery(// "from "+clazz.getSimpleName()+"where id in(:ids)")// .setParameterList("ids", ids)// .list(); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#findAll() */ public List<T> findAll(){ return getSession().createQuery(// "from "+clazz.getSimpleName())// .list(); } /* (non-Javadoc) * @see com.liang.ssh2.base.BaseDao#getPage(long, java.lang.Long, com.liang.ssh2.util.QueryHelper) */ public Page getPage(long currentPage,Long pageSize,QueryHelper queryHelper){ //如果用户没有动态指定pageSize,则读取配置文件 if(pageSize==null){ pageSize=Configuration.getPageSize(); } //获得参数 List<Object> parameters = queryHelper.getParameters(); Query query = getSession().createQuery(queryHelper.getQueryListHql()); if(parameters!=null&¶meters.size()>0){ for (int i = 0; i < parameters.size(); i++) { query.setParameter(i, parameters.get(i)); } } query.setFirstResult((int) ((currentPage-1)*pageSize)); query.setMaxResults(pageSize.intValue()); List recordList = query.list(); // 查询总记录数 query = getSession().createQuery(queryHelper.getQueryCountHql()); // 注意空格! if (parameters != null && parameters.size() > 0) { // 设置参数 for (int i = 0; i < parameters.size(); i++) { query.setParameter(i, parameters.get(i)); } } Long recordCount = (Long) query.uniqueResult(); // 查询 return new Page(currentPage, pageSize, recordCount, recordList); } }
</pre><pre name="code" class="java">package com.liang.ssh2.service.impl; import org.springframework.stereotype.Service; import com.liang.ssh2.base.BaseDaoImpl; import com.liang.ssh2.entity.User; @Service public class UserServiceImpl extends BaseDaoImpl<User>{ }
想偷个懒,少写个接口,也不容易啊!!!!!
利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。