ForEach 方法中的类强制转换异常
Posted
技术标签:
【中文标题】ForEach 方法中的类强制转换异常【英文标题】:Class Cast Exception In ForEach Method 【发布时间】:2018-05-15 08:08:03 【问题描述】:这是一个使用 Spring 5 和 Hibernate 5 的 ORM 应用程序 我在 DAO 层使用 Hibernate Callback 接口来获取特定 id 之间的员工记录。我使用了命名参数 :min & :max。虽然它成功生成了查询,但在服务层却抛出了异常。 我无法找到该异常的根本原因
DAOIMPL ------------
private static final String get_Records_By_Range="SELECT id,name,company,address,salary FROM EmployeeHLO where id>=:min and id<=:max";
@SuppressWarnings("unchecked")
@Override
public List<EmployeeHLO> getRecordsByIdRange(int start, int end) throws Exception
List<EmployeeHLO> listHlo= null;
listHlo= ht.execute(new HibernateCallback<List<EmployeeHLO>>()
@Override
public List<EmployeeHLO> doInHibernate(Session ses) throws HibernateException
Query query= null;
query= ses.createQuery(get_Records_By_Range);
query.setInteger("min", start);
query.setInteger("max", end);
List<EmployeeHLO> listHloo= query.list();
return listHloo;
);
return listHlo
服务IMPL -------------------
@Override
public List<EmployeeDto> getRecordsByRange(int start, int end) throws Exception
List<EmployeeHLO> listHlo= null;
List<EmployeeDto> listDto= new ArrayList<EmployeeDto>();
//get records from dao
listHlo= dao.getRecordsByIdRange(start, end);
//copy hlo to dto
listHlo.forEach(hlo-> //getting error in this line
EmployeeDto dto= new EmployeeDto();
BeanUtils.copyProperties(hlo, dto);
listDto.add(dto);
);
return listDto;
测试 ----------
try
//get record by range
listDto= service.getRecordsByRange(1, 5);
listDto.forEach(rangeDto->
System.out.println(rangeDto.getId()+" "+rangeDto.getName()+" "+rangeDto.getCompany()+" "+rangeDto.getAddress()+" "+rangeDto.getSalary());
);
Domain(EMployeeHLO) && EmployeeDTo 也包含相同的属性 ----------------------
import java.io.Serializable;
public class EmployeeHLO implements Serializable
private int id;
private String name;
private String company;
private String address;
private float salary;
public int getId()
return id;
public void setId(int id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getCompany()
return company;
public void setCompany(String company)
this.company = company;
public String getAddress()
return address;
public void setAddress(String address)
this.address = address;
public float getSalary()
return salary;
public void setSalary(float salary)
this.salary = salary;
错误 ------------
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.st.domain.EmployeeHLO
at java.util.ArrayList.forEach(Unknown Source)
at com.st.service.EmployeeServiceImpl.getRecordsByRange(EmployeeServiceImpl.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:338)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:197)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy31.getRecordsByRange(Unknown Source)
at com.st.test.Test.main(Test.java:46)
EmployeeHLO.hbm.xml ------------------------------------
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.st.domain.EmployeeHLO" table="orm_table">
<id name="id" column="id" length="10" type="int">
<generator class="increment"></generator>
</id>
<property name="name" column="name" type="string" not-null="true" length="50"></property>
<property name="company" column="company" type="string" not-null="true" length="50"></property>
<property name="address" column="address" type="string" not-null="true" length="50"></property>
<property name="salary" column="salary" type="float" precision="2" not-null="true" length="10"></property>
</class>
<query name="HQL_GET_RECORDS_BY_RANGE">
<![CDATA[
from EmployeeHLO where id>=:min and id<=:max
]]>
</query>
</hibernate-mapping>
【问题讨论】:
【参考方案1】:您必须选择实体,而不是它的所有字段或休眠将返回这些字段的列表,例如Object[] 的列表,因为有多种类型。
尝试将其更改为:
"SELECT emp FROM EmployeeHLO emp where emp.id>=:min and emp.id<=:max"
emp
是表 EmployeeHLO
的别名,为了简单起见,我们可以在查询中使用它。
当您引用实体的字段时,最好指向实体 where emp.id
而不是 where id
,因为您可以虚拟地从多个表中进行选择或连接它们。
在 select 子句中,如果您想返回实体而不是代表所选字段的其他构造(例如,它始终是 List<Object[]>
),则必须通过别名选择整个表。
这样,hibernate 会发挥他的作用,并为每行返回一个实体实例,其中字段已经填充了行值
【讨论】:
感谢兄弟它的工作,但虽然我不是那么强大的 sql 你能解释一下这个查询。 emp 在这里做了什么,我的查询出了什么问题? 已更新,但我必须告诉你这不是简单的 sql。 Hibernate 查询语言 (HQL) 是您在执行 .createQuery 时必须使用的 yaa 我已经尝试过另一个查询,即 FROM EmployeeHLO WHERE id>=:min 和 id 你已经采取了。在您的查询中使用“emp”有什么用。以上是关于ForEach 方法中的类强制转换异常的主要内容,如果未能解决你的问题,请参考以下文章