利用泛型抽取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)
上一篇 2022年1月20日 上午8:00
下一篇 2022年1月20日 上午8:00


相关推荐

  • 医咖会SPSS免费教程学习笔记—配对卡方检验

    医咖会SPSS免费教程学习笔记—配对卡方检验配对卡方检验(McNemar’s检验)1.需要满足的假设:(1)观测变量是二分类变量(互斥)(2)分组变量有两类(有三类及以上的用Cochran’sQ检验)2.实操分析—非参数检验—相关样本—勾选“自动比较实测数据和假设数据”—选择上方工具栏中的“字段”—将分组变量拖入“检验字段”中—选择上方工具栏中“设置”—勾选定制检验—选择“麦克尼马尔检验”—运行…

    2022年8月31日
    7
  • Java中的join方法原理详解「建议收藏」

    Java中的join方法原理详解「建议收藏」1.synchronized中的对象锁是线程的实例我们可以使用同步语句块的方式对需要同步的代码进行包裹。Objectobj=newObject();synchronized(obj){   obj.wait();    //线程在这里等待}此时线程会在obj.wait()处等待,如果想继续执行,此时需要别的线程通过notify、notifyAll唤醒或者中断。但是如果o…

    2022年5月1日
    56
  • spring boot + kafka 使用详细步骤[通俗易懂]

    spring boot + kafka 使用详细步骤[通俗易懂]一,Kafka的安装以及配置1.下载文件wgethttp://mirror.bit.edu.cn/apache/kafka/0.11.0.0/kafka_2.11-0.11.0.0.tgz2.安装tarxzvfkafka_2.11-0.11.0.0.tgz-C/usr/local/3.配置(服务器在阿里云ECS上)vi%kafka_home%/server…

    2022年5月9日
    143
  • 50_Pandas读取 Excel 文件 (xlsx, xls)

    50_Pandas读取 Excel 文件 (xlsx, xls)50 Pandas 读取 Excel 文件 xlsx xls 要使用 pandas 将 Excel 文件 扩展名 xlsx xls 作为 pandas DataFrame 读取 请使用 pandas read excel 函数 这里 将描述以下内容 openpyxl xlrd 的安装 pandas read excel 的基本用法通过编号 工作表名称指定要读取的工作表 参数 sheet name 读取一张 Sheet 读取多张 Sheet 加载所有 Sheet 指定标头 索引 参数 he

    2026年3月18日
    2
  • HTTP Status 415 – Unsupported Media Type「建议收藏」

    HTTP Status 415 – Unsupported Media Type「建议收藏」HTTPStatus415–UnsupportedMediaType今天在测试springmvc的restful接口时候遇到了一个问题:通过body传参报错HTTPStatus415–UnsupportedMediaType简述restful接口传参方式restful推荐的传参方式:1.get/delete请求RequestParam,请求的url类似于http…

    2022年5月26日
    51
  • 无法与服务器建立安全链接怎么解决_无法与应用服务器建立连接

    无法与服务器建立安全链接怎么解决_无法与应用服务器建立连接http://www.cocoachina.com/bbs/read.php?tid=1686383nscurl–ats-diagnostics–verbose https://b

    2022年8月4日
    11

发表回复

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

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