hibernate的createSQLQuery与createQuery的返回数组与对象问题

简介: 本文原址 : http://stta04.javaeye.com/blog/377633昨晚帮同事看代码到凌晨2点多,今早6点醒来发现他发来信息说报空指针错误,实在无法入睡,起来自己测试了一下,控制台还真的报:2009-4-25 8:12:34 org.

本文原址 : http://stta04.javaeye.com/blog/377633

昨晚帮同事看代码到凌晨2点多,今早6点醒来发现他发来信息说报空指针错误,实在无法入睡,起来自己测试了一下,控制台还真的报:

2009-4-25 8:12:34 org.apache.catalina.core.ApplicationContext log
信息: Java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.miracle.dm.doc.catalog.model.DocCatalogInfo

原来的查询语句:

String sql = "select a.* from tb_doc_catalog a where a.cat_code like '"+catCode+"%'";
Session session = this.getSession();
try {
List catNameList = session.createSQLQuery(sql).list();
return catNameList ;
} finally {
releaseSession(session); //释放session
}

分析:原来是查询出来的字段并不能自动转换为bean对象。

解决思路一(采用hql查询):

String sql = "select a from DocCatalogInfo a where a.catCode like '"+catCode+"%'";
List catNameList =getHibernateTemplate().find(sql);
return catNameList ;
ok,测试一下发现没问题,看来还是因为用原生sql查询的原因,网上搜一下:createsqlQuery返回对象,看到一篇文章才觉悟到:

解决思路二(采用原生sql查询):

String sql = "select a.* from tb_doc_catalog a where a.cat_code like '"+catCode+"%'";
Session session = this.getSession();
try {
List catNameList = session.createSQLQuery(sql).addEntity(DocCatalogInfo.class).list();
return catNameList ;
} finally {
releaseSession(session); //释放session
}

又ok了。

该篇文章也贴上来:

hibernate 中createQuery与createSQLQuery两者区别是:
前者用的hql语句进行查询,后者可以用sql语句查询
前者以 hibernate生成的Bean为对象装入list返回
后者则是以对象数组进行存储
所以使用createSQLQuery有时候也想以 hibernate生成的Bean为对象装入list返回,就不是很方便
突然发现createSQLQuery有这样一个方法可以直接转换对象
Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);
XXXXXXX 代表以 hibernate生成的Bean的对象,也就是数据表映射出的Bean。
呵呵以后多注意,还是时不时的要看看 hibernate各个对象方法的使用。

还有另外一个相关的小细节应注意:
比如有这样一个po
PO: User.class
properties: userId,userName
DDL: create table tuser (userid varchar(10),username varchar(20));
当执行:
session.createQuery("from User u").list()时生成的SQL:
  select userid,username from tuser;
当执行:

session.createQuery("from User u").iterator()时生成的SQL:
  
select userid from tuser;
  
可以看出list()一次将数据从数据库中读出直接填充到List中
  
iterator()将数据的主键从数据库中读出,当循环这个Iterator时才添加执行:
  
select userid,username from user where userid=?;把数据读出。
在不同的应用范围使用不同的方法,具体在 hibernate应用中应当注意。
 
 
 
 
 
第二种解释

今天想着做一个分页的DAO,用hibernate数据库的Question表中取5个数据,这个分页是每次都从数据库中取出一段数据,而不是一次性取所有的数据。

一开始,我的DAO是这么写的:

public List findallquestion(int num,int pagesize){
   int num2=(num-1)*5;
   Session session=getSession();
   String sql="select * from Question limit :num1,:size";
   Query query = session.createSQLQuery(sql);
   query.setParameter("num1",num2);
   query.setParameter("size", pagesize);
   List list=query.list();
   Question question=null;
    for(int i=0;i<list.size();i++)
   {
    question = (Question)list.get(i);
    System.out.print("ID"+question.getId());
    System.out.println("TITLE"+question.getTitle());
   }
   return list;
}

奇怪的事情就这么发生了,

第一,出现了报错:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.njcit.bbs.Question

第二,question对象里面取不出值

这我就奇怪了,我用list.size()发现长度的确是5,和我需要的长度是一致的,为什么会报错,而且取不出呢?

问题应该是question = (Question)list.get(i);list里面不是存放的一条条记录么,为什么不能转成我需要的Bean呢

网上找了很多资料,最后在这里找到了想要的东西:http://helloandy2009.javaeye.com/blog/614369

我们一般在用Hibernate写增删查改的时候,有2中方式,一种是HQL,一种是SQL

实例:

我要执行的语句是:select * from Question

HQL是这么写的:

Session session = getSession();

String hql="from Question";

List list = (Question)session.createQuery(hql).list();

System.out.println(list.getTitle());

测试正常

SQL写法:

Session session=getSession();

String sql="select * from Question"

List list=(Question)session.createSQLQuery(sql).list();//会发生类型转换错误,就是文章开头的那个错误

原因:
HQL中

String hql="from Question";

List list = (Question)session.createQuery(hql).list();

会根据你的hql语句,自动将session.createQuery(hql).list()的返回对象以hibernate生成的Bean为对象装入list返回

SQL中

String sql="select * from Question"

List list=(Question)session.createSQLQuery(sql).list();

则是以对象数组进行存储返回

一句话:HQL:返回list装的是Bean SQL:返回对象就是一数组,数组在转为Question对象时,当然会报错。

解决方法:

第一种:直接老老实实用HQL去写吧= =参数化就百度“Hibernate 参数绑定”就行

第二种:使用原生SQL,调用其中的一个方法addEntity()

String sql="select * from Question";

Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class);

List list = (Question)query;

这样 list中也就装的是Question这洋一个个Bean对象了,问题还是不知道如何参数化= =!

找到方法了:

Hibernate中的分页语句可以这么写

     session = HibernateUtils.getSession();
     session.beginTransaction();
     Query query = session.createQuery("from User");
     query.setFirstResult(0);//从第一条记录开始
     query.setMaxResults(4);//取出四条记录
     List userList = query.list();

相关文章
|
8月前
|
SQL 缓存 Java
Hibernate对象状态之间的神奇转换
Hibernate对象状态之间的神奇转换
|
5月前
|
SQL Java 数据库连接
Hibernate - QBC和本地SQL对象检索详解
Hibernate - QBC和本地SQL对象检索详解
29 0
|
5月前
|
SQL Java 数据库连接
Hibernate - HQL对象检索详解
Hibernate - HQL对象检索详解
24 0
|
5月前
|
SQL Java 关系型数据库
Hibernate - 对象关系映射文件(*.hbm.xml)详解
Hibernate - 对象关系映射文件(*.hbm.xml)详解
107 1
|
5月前
|
存储 缓存 Java
Hibernate - Session方法与持久化对象详解
Hibernate - Session方法与持久化对象详解
73 0
|
10月前
|
SQL Java 数据库连接
【java】——Hibernate持久化对象的三个状态
当我正在上课的时候这时老师出去去厕所了(session关闭),这个时候我的心飞向了外面的远方,这时我就处于离线状态。
|
11月前
|
SQL Java 数据库连接
Hibernate中的Session对象
Hibernate中的Session对象
58 0
|
Java 数据库连接
Java 最常见的面试题:hibernate 对象有哪些状态?
Java 最常见的面试题:hibernate 对象有哪些状态?
|
缓存 Java 数据库连接
Hibernate保存对象出现 org.hibernate.NonUniqueObjectExce
Hibernate保存对象出现 org.hibernate.NonUniqueObjectExce
|
Java 数据库连接 数据库
Hibernate的方法获取对象后,对象调用set后会自动更新数据库内容的解决办法
Hibernate的方法获取对象后,对象调用set后会自动更新数据库内容的解决办法
714 0