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

当启动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啊!!!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116530.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux安装svn服务器的两种方式

    linux安装svn服务器的两种方式操作环境:CentOS7.264位==============第一种:采用压缩包安装:比如你们公司服务器上安装软件有自己的规定,一般会采用压缩包安装。==============第一步:SVN服务器端压缩包下载下载地址:http://mirrors.cnnic.cn/apache/subversion/ 我下载的是subversion-1.8.19版本,下载好的压缩包置于目录/usr/loc…

    2022年7月19日
    16
  • Pycharm远程开发_pycharm远程linux开发

    Pycharm远程开发_pycharm远程linux开发需要使用远程的linux服务器,但是因为pycharm很方便、希望在自己电脑上开发。这里直接使用pycharm进行远程开发。1.配置连接配置连接可以点击test_connection进行测试2.映射文件夹为了上传本地文件到服务器,以及把服务器下载到本地,需要分别设置这两个文件夹的路径3.设置编译器连接好了服务器,设置好了文件映射关系,接下来就是要使用远端的服务器了。设置成服务器端的解释器跟路径就行。(路径好像是根据之前的设置生成的)4.使用写一个简单的代码,run一下其实

    2022年8月25日
    8
  • Mac Python第三方库安装「建议收藏」

    Mac Python第三方库安装「建议收藏」安装方式有两种:(1)PyCharm自带的package管理工具(2)终端pip3安装;例如要安装:requests库一、使用PyCharm自带的package管理工具进行安装:Preferences->Project->ProjectInterpreter,点击左下角的“+”直接搜索requests,安装(2)终端输入:$…

    2022年10月10日
    2
  • pip和conda安装与卸载tensorflow、pycharm中使用特定的conda虚拟环境「建议收藏」

    pip和conda安装与卸载tensorflow、pycharm中使用特定的conda虚拟环境「建议收藏」写吴恩达dp作业做的准备参考https://blog.csdn.net/ccgcccccc/article/details/89058445根据他的配置要求来配置文件pipinstalltensorflow==1.13.0rc2-ihttps://pypi.tuna.tsinghua.edu.cn/simple或者-ihttps://mirrors.aliyun.com/py…

    2022年6月22日
    47
  • 领域驱动实践总结(基本理论总结与分析V+架构分析与代码设计+具体应用设计分析)

    领域驱动实践总结(基本理论总结与分析V+架构分析与代码设计+具体应用设计分析)领域驱动实践总结一:基本理论总结与分析一、领域驱动设计两大设计:战略设计和战术设计二、理解和分析领域+子域+核心域+通用域+支撑域三、理解和分析界限上下文,定义领域边界四、理解和分析实体和值对象五、理解和分析聚合思想:聚合和聚合根六、理解很分析领域事件来解耦微服务…

    2022年4月26日
    33
  • linux恢复硬盘初始状态,初始化Linux数据盘(fdisk)[通俗易懂]

    linux恢复硬盘初始状态,初始化Linux数据盘(fdisk)[通俗易懂]初始化Linux数据盘(fdisk)TkV南京数据恢复-西数科技:硬盘/手机/SSD数据恢复专家.025-8360863618913825606查看PDFTkV南京数据恢复-西数科技:硬盘/手机/SSD数据恢复专家.025-8360863618913825606分享操作场景本文以云服务器的操作系统为“CentOS7.464位”为例,采用fdisk分区工具为数据盘设置分区。TkV…

    2022年5月27日
    58

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号