想利用泛型抽取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{
@Resource
private SessionFactory sessionFactory;
Class clazz;
/**
* 通过反射获取參数类型
*/
public BaseDaoImpl(){
System.out.println(this);
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
clazz=(Class) 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 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 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
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{
}
注意我是把@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 {
/**
* 保存实体
* @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 getByIds(Long[] ids);
public abstract List 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 implements BaseDao{
@Resource
private SessionFactory sessionFactory;
Class clazz;
/**
* 通过反射获取參数类型
*/
public BaseDaoImpl(){
System.out.println(this);
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
clazz=(Class) 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 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 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
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{ }
想偷个懒。少写个接口。也不easy啊!!!!!