spring 整合 hibernate 使用泛型的异常
本帖最后由 xiaogutou1 于 2013-10-20 16:52:47 编辑 BasicDao 代码:
package com.util;
import org.springframework.orm.hibernate3.HibernateTemplate;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
public class BasicDao<T> {
private HibernateTemplate hibernateTemplate;
private Class entityClass;
public BasicDao(){
Type genType = getClass().getGenericSuperclass();
Type[] params=((ParameterizedType)genType).getActualTypeArguments();
entityClass = (Class)params[0];
}
public void setHibernateTemplate(HibernateTemplate h){
this.hibernateTemplate=h;
}
//添加
public void insert(T entity){
hibernateTemplate.save(entity);
}
//修改
public void update(T entity){
hibernateTemplate.update(entity);
}
//删除
public void delete(T entity){
hibernateTemplate.delete(entity);
}
//查询
public T get(Serializable id){
return (T)hibernateTemplate.get(entityClass, id);
}
//按条件查询
public List<T> find(String hql,Object param){
return (List<T>)hibernateTemplate.find(hql, param);
}
public HibernateTemplate getHibernateTemplate(){
return hibernateTemplate;
}
}
UserDao代码:
package com.user.dao;
import com.jdbc.bean.User;
import com.util.BasicDao;
public class UserDao extends BasicDao<User> {
}
测试代码:
public static void main(String[] arg0){
Test test = new Test();
UserDao userDao = new UserDao();
List results = userDao.find("from T_USERwhere USER_NAME LIKE ?", "%zhanghang%");
System.out.println("name password lastTime lastIp");
for(int i=0;i<results.size();i++){
System.out.println(((User)results.get(i)).getUserName()+" "+((User)results.get(i)).getPassword()+" "+((User)results.get(i)).getLastTime()+" "+((User)results.get(i)).getLastIp());
}
}xml配置文件:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="${driver}"
p:url="${url}"
p:username="${name}"
p:password="${password}"
/>
<bean id="locationSessionFactoryBean" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean" p:dataSource-ref="dataSource">
<property name="mappingLocations">
<list>
<value>classpath*:/hibernate/user.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" p:sessionFactory-ref="locationSessionFactoryBean"></bean>
<bean id="BasicDao" class="com.util.BasicDao" p:hibernateTemplate-ref="hibernateTemplate"> </bean>
在通过测试代码进行测试的时候 报类型转换异常:
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.util.BasicDao]: Constructor threw exception; nested exception is java.lang.ClassCastException: java.lang.Class
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:983)
... 14 more
Caused by: java.lang.ClassCastException: java.lang.Class
at com.util.BasicDao.<init>(BasicDao.java:18)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
... 16 more
hibernate spring 泛型 异常
[解决办法]
估计是你BasicDAO的构造函数里出问题,你要获得实体类的类型,用注解吧,比这个简单
[解决办法]
BasicDAO 应该不能实例化吧,你想实例化的应该是UserDao?,Spring文件里面配置换下试试看。
[解决办法]
public BasicDao(){
//Type genType = getClass().getGenericSuperclass();
//Type[] params=((ParameterizedType)genType).getActualTypeArguments();
//entityClass = (Class)params[0];
}
把构造方法里面的代码先注释掉,再测试一下。还有那个public T get(Serializable id)这个方法也注释掉,因为用到了entityClass.
先确定问题在哪里。如果注释掉运行find能找到数据而且不报错的话就想想如何替代这个entityClass的获取方式。
因为没有使用过SSH框架,意见只供参考。
[解决办法]
我不熟悉你的BasicDao构造方法里获取实体类的方法,所以也不知道是什么错,给你提供一种方法,我也写过类型的泛型DAO,获取实体类我是用的注解
首先定义一个注解
package com.web.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于标注该DAOImpl类所对应的实体类的名字是什么,以便获取相应的实体类
* @author
*
*/
@Retention(RetentionPolicy.RUNTIME)//代表在运行期保留注解
@Target(ElementType.TYPE)//代表用于类中
public @interface EntityClassName {
/**
* 标注对应的实体类名
* @return 对应的实体类名
*/
String value();
}
然后在BasicDao里写一个方法
/**
* 获取该DAO实现类的对应的实体类
* @return 实体类
* @throws Exception
*/
private Class<?> getPOJOClass() throws Exception{
Class<?> pojoClass = null;
//先判断该实现类的实体类注解是否存在
if(this.getClass().isAnnotationPresent(EntityClassName.class)){
//如果存在获取该注解(即实体类的名字)
String className = ((EntityClassName)getClass().
getAnnotation(EntityClassName.class)).value();
//通过反射获取该实体类
pojoClass = Class.forName(className);
}
return pojoClass;
}
你要用到实体类的时候就用这个方法获取
然后在你的UserDAO上打上这个注解
package com.user.dao;
import com.jdbc.bean.User;
import com.util.BasicDao;
@EntityClassName("com.web.bean.User") //标注该DAO类是对应于哪个实体类,(包名改成你自己的)
public class UserDao extends BasicDao<User> {
}