hibernate命名查询时总是报类型转换异常:java.lang.ClassCastException

本文介绍了Hibernate框架中的命名查询功能,包括其定义、好处及多种实现方式,并提供了具体的配置示例和测试代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

异常描述如下;

1、在user.hbm.xml中配置如下<sql-query>

<!-- 如果sql-query放置在class里面,在引用时需加上包名和类名,即:com.summer.entity.User.mySQLquery -->
		<sql-query name="mySQLquery">			
			<![CDATA[ select * from simpro_user]]>
		</sql-query>

2、测试代码如下:

	public static void getByNamedQuery(String queryName){
		//queryName = "com.summer.entity.User.mySQLquery";
		Session session = HibernateUtil.getSession();
		Query q = session.getNamedQuery(queryName);		
		List<User> users = q.list();
		System.out.println("=========start:NamedQuery===================");
		for (Object user : users) {
			System.out.println((User)user);
		}
		System.out.println("=========end:NamedQuery===================");
	}
3、异常信息如下:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.summer.entity.User
4、解决方法如下:

以下内容为hibernate命名查询学习总结:

一、什么是命名查询? 
Hibernate允许在映射文件(xxx.hbm.xml,可以是实体类的映射文件,如User.hbm.xml,也可以是自定义的映射文件,如:namedSQL.hbm.xml)中定义字符串形式的查询语句,这种查询方式成为命名查询。然后在hibernate.cfg.xml中引入命名查询文件;
 

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration
    PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
	<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
	<property name="connection.url">jdbc:oracle:thin:@192.168.1.1:1521:ORCL</property>
	<property name="connection.password">root</property>
	<property name="connection.username">root</property>
	
	<property name="dialect">org.hibernate.dialect.OracleDialect</property>
	<property name="show_sql">true</property>
	<!-- <property name="hbm2ddl.auto">update</property>	 -->
	<!-- 二级缓存的配置 -->
	<property name="cache.use_second_level_cache">true</property>
	<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
	<!--启动查询缓存:默认是关闭的。如:默认使用Query\Criteria查询不使用缓存的-->
	<property name="cache.use_query_cache">true</property>
	<!-- 输出统计信息 -->
	<property name="generate_statistics">true</property>	
		
	<mapping resource="User.hbm.xml"/>
	<!--配置映射的二级缓存-->
	<class-cache usage="read-write" class="com.summer.entity.User"/>
</session-factory>	
</hibernate-configuration>

二、使用命名查询有什么好处? 
由于使用Hibernate的HQL常常需要在Java代码中写字符串查询语句,HQL混杂在代码之间,破坏代码可读性,通过使用命名查询,可以使业务逻辑和查询语句分离,使您专注于查询,而避免了 SQL 或者 HQL 代码分散于整个应用程序中的情况。 
可以应用命名查询做复杂查询的处理 

三、命名查询如何实现? 
介绍下面几种方式: 

方法一:在配置文件中<class/>标记的下面,声明查询语句 

方法二:也可以在配置文件中<class/>标记的里面,声明查询语句, 但是java代码调用时需要指定(包+类+配置名) 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.summer.entity"
	auto-import="true">
	<class name="User" table="SIMPRO_USER">

		<id name="id" column="USER_ID" type="java.lang.String">
			<generator class="uuid.hex"></generator>
		</id>
		<property name="loginId" column="LOGIN_ID" type="java.lang.String" />
		<property name="orgId" column="ORG_ID" type="java.lang.String" />
		<property name="userName" column="USER_NAME" type="java.lang.String" />
		<property name="password" column="PASSWORD" type="java.lang.String" />
		<property name="email" column="EMAIL" type="java.lang.String" />
		<property name="phoneNum" column="PHONE_NUM" type="java.lang.String" />
		<property name="status" column="STATUS" type="java.lang.String" />

		<!-- 方式一:如果sql-query放置在class里面,在引用时需加上包名和类名,即:com.summer.entity.User.mySQLquery -->
		<query name="mySQLquery">			
			<![CDATA[ from User]]>
		</query>

	</class>
	<!-- 方式二:若sql-query放置在class外面,则可以程序中直接引用,即:myNamedSQLquery -->
	<query name="myNamedSQLquery">
		<![CDATA[ from User]]>
	</query>	

</hibernate-mapping>
测试代码如下:

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.summer.entity.User;
import com.summer.util.HibernateUtil;

public class TestHibernate {

	public static void main(String[] args) {
		//命名查询:
		getByNamedQuery("com.summer.entity.User.mySQLquery");
		getByNamedQuery("myNamedSQLquery");
		//原生SQL查询
		getBySql("select * from simpro_user");
	}
	
	public static void getByNamedQuery(String queryName){
		//queryName = "com.summer.entity.User.mySQLquery";
		Session session = HibernateUtil.getSession();
		Query q = session.getNamedQuery(queryName);		
		List<User> users = q.list();
		System.out.println("=========start:NamedQuery===================");
		for (Object user : users) {
			System.out.println((User)user);
		}
		System.out.println("=========end:NamedQuery===================");
	}
	
	public static void getBySql(String sql){
		Session session = HibernateUtil.getSession();
		SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
		List<User> users = query.list();
		System.out.println("=========start:sqlQuery===================");
		for (User user : users) {
			System.out.println(user);
		}
		System.out.println("=========end:sqlQuery===================");
	}

}


方法三:使用原生sql查询<sql-query>,使用此种方式必须把表所有的列写全才可以,否则会出现‘列名无效'的错误 ,除非你使用return-scalar来设置字段类型。

<hibernate-mapping> 
<class name="com.test.bean.Student" table="student" catalog="users"> 
<id name="id" type="integer"> 
<column name="id" /> 
<generator class="identity" /> 
</id> 
<property name="name" type="string"> 
<column name="name" length="11" /> 
</property> 
<property name="age" type="integer"> 
<column name="age" /> 
</property> 
<property name="sex" type="string"> 
<column name="sex" length="2" /> 
</property> 
</class> 
<!-- 定义查询语句 --> 
<sql-query name="findStudentByName"> 
<return alias="s" class="com.test.bean.Student"> 
</return> 
<![CDATA[select {s.*} from student s where s.name = :name]]> 
</sql-query> 
</hibernate-mapping> 
方法四:使用原生sql查询<sql-query>, 如果应用return-scalar来设置字段类型, 就可以实现查询部分字段。
<hibernate-mapping> 
<class name="com.test.bean.Student" table="student" catalog="users"> 
<id name="id" type="integer"> 
<column name="id" /> 
<generator class="identity" /> 
</id> 
<property name="name" type="string"> 
<column name="name" length="11" /> 
</property> 
<property name="age" type="integer"> 
<column name="age" /> 
</property> 
<property name="sex" type="string"> 
<column name="sex" length="2" /> 
</property> 
</class> 
<!-- 定义查询语句 --> 
<sql-query name="findStudentByName"> 
<return-scalar column="name" type="string"/> 
<return-scalar column="age" type="integer"/> 
<![CDATA[select s.name , s.age from student s where s.name = :name]]> 
</sql-query> 
</hibernate-mapping> 
public List<Object[]> query(){ 
Session session = HibernateSessionFactory.getSession(); 
Query query = session.getNamedQuery("findStudentByName"); 
query.setString("name", "zhangsan"); 
List<Object[]> list = query.list(); 
return list; 
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值