使用Hibernate返回自定义类型时报错的问题
来源:互联网 发布:网络信息时代的利与弊 编辑:程序博客网 时间:2024/06/03 22:51
转载自: http://blog.csdn.net/java_zys/article/details/68940691
数据库为oracle,在使用Hibernate查询时想要返回自定义的pojo类型,遇到类型转换的异常。如下面的命名查询希望返回数据行为typeClass类型
- Query localQuery = session.getNamedQuery("findPersonInfo");
- localQuery.setResultTransformer(Transformers.aliasToBean(typeClass)).list();
运行后报错,错误信息如下:
- java.lang.ClassCastException: com.test.pojo.TestPojo cannot be cast to java.util.Map
- at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102)
- at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:78)
- at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:75)
- at org.hibernate.loader.custom.CustomLoader.getResultList(CustomLoader.java:434)
- at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430)
- at org.hibernate.loader.Loader.list(Loader.java:2425)
- at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335)
- at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2153)
- at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:987)
- at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:148)
- at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1410)
TestPojo类如下:- public class TestPojo {
- private String id;
- private String username;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- }
原因是使用oracle时返回的字段默认为大写,导致转换失败。Hibernate可以通过自定义ResultTransformer类来解决这个问题,给出参考代码:
- import java.lang.reflect.Field;
- import java.util.List;
- import org.apache.commons.beanutils.BeanUtilsBean;
- import org.hibernate.HibernateException;
- import org.hibernate.transform.ResultTransformer;
-
-
-
-
-
-
-
-
-
- public class IgnoreCaseResultTransformer implements ResultTransformer {
-
- private static final long serialVersionUID = -3779317531110592988L;
-
- private final Class<?> resultClass;
- private Field[] fields;
- private BeanUtilsBean beanUtilsBean;
-
- public IgnoreCaseResultTransformer(final Class<?> resultClass) {
- this.resultClass = resultClass;
- this.fields = this.resultClass.getDeclaredFields();
- beanUtilsBean=BeanUtilsBean.getInstance();
- }
-
-
-
-
-
- public Object transformTuple(final Object[] tuple, final String[] aliases) {
- Object result;
- try {
- result = this.resultClass.newInstance();
- for (int i = 0; i < aliases.length; i++) {
- for (Field field : this.fields) {
- String fieldName = field.getName();
-
- if (fieldName.equalsIgnoreCase(aliases[i].replaceAll("_", ""))) {
- beanUtilsBean.setProperty(result, fieldName, tuple[i]);
- break;
- }
- }
- }
- } catch (Exception e) {
- throw new HibernateException("Could not instantiate resultclass: " + this.resultClass.getName(), e);
- }
- return result;
- }
-
- @SuppressWarnings("rawtypes")
- public List transformList(final List collection) {
- return collection;
- }
- }
使用方法:
- Query localQuery = paramSession.getNamedQuery("findPersonInfo");
- localQuery.setResultTransformer(new IgnoreCaseResultTransformer(typeClass)).list();