• 利用泛型抽取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是不用放的

    当启动server时会报错: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>{
    
    }
    

    想偷个懒。少写个接口。也不easy啊!!!!!










  • 相关阅读:
    奇异值分解(SVD)详解及其应用
    注意力机制最新综述解读
    双目立体视觉的数学原理
    区域生长算法原理及MATLAB实现
    “error LNK2019: 无法解析的外部符号”的几种可能原因
    3D Slicer Adding MRML
    3D Slicer CreateModels-Module Analysis
    3D Slicer 结构的实例分析IGSReader
    3D Slicer VS-Qt5VSaddin-qt4.8.7dev
    3D Slicer Debug or Dev-170918
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5080150.html
Copyright © 2020-2023  润新知