Это приложение ORM, использующее Spring 5 и Hibernate 5
.
Я использую интерфейс обратного вызова Hibernate на уровне DAO, чтобы получить запись о сотрудниках между определенными идентификаторами. Я использовал именованный параметр : мин & :Максимум. Хотя он успешно генерирует запрос, но на уровне обслуживания выдает исключение.
Я не могу определить основную причину этого исключения
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
Обслуживание
-------------------
@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());
});
Домен (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)
СотрудникHLO.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>




Вы должны выбрать объект, и не все его поля или спящий режим вернут список этих полей, например. Список 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. Язык запросов Hibernate (HQL) - это то, что вам нужно использовать, когда вы делаете .createQuery
yaa Я пробовал с другим запросом, то есть FROM EmployeeHLO WHERE id> =: min и id <=: max ** это тоже сработало, поэтому в соответствии с отраслевым стандартом использовать ссылку типа ** "emp", как вы сделали. Какая польза от слова "emp" в вашем запросе.
спасибо, братан, это сработало, но хотя я не так уж силен в sql, вы можете немного объяснить этот запрос. что здесь делает emp и что было не так в моем запросе?