¿Cómo cargar un archivo hibernado 'xxx.hbm.cfg' en un proyecto JPA 2.0?
-
27-10-2019 - |
Pregunta
Acabo de comenzar una aplicación Roo Spring con Hibernate como proveedor JPA2.0. Estoy usando los frascos de la siguiente manera:
hibernato-core-3.6.4.final.jar
Hibernate-Commons-Annotations-3.2.0.Jar
Hibernate-EntityManager-3.6.4.Final.Jar
Hibernate-JPA-2.0-API-1.0.0.Final.Jar
Hibernate-Validator-4.1.0.Final.Jar
Estoy usando anotaciones para manejar el aspecto transaccional de la aplicación, no hay problema allí.
Pero hay otras partes de la aplicación que requieren consultas muy complejas, y la forma en que la había manejado en Hibernate antes era crear un archivo de asignación, por ejemplo, myBigDWquery.hbm.xml) donde especificaría mi consulta y su objeto de asignación, un Pojo. No es una @Entity. Esto funciona bien.
Sin embargo, a través de otra pregunta que publiqué anteriormente, descubrí que en JPA 2.0 no puede tener consultas asignadas a un POJO, todo debe asignarse a un @Entity (¿una tabla de DB no?).
Entonces mi pregunta es la siguiente:
¿Hay alguna forma de que pueda tener mi 'mybigdwquery.hbm.xml' archivo cargado en mi persistencia.xml como hbm.xml para que pueda llamar a la consulta nombrada?
Mi persistencia.xml es el siguiente:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> -->
<!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
</properties>
</persistence-unit>
</persistence>
El archivo que necesito cargar:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="edu.kdc.visioncards.pojo">
<class name="AttendanceBreakDown">
<cache usage="read-only" />
<id name="studentName"/>
<property name="pupilId"></property>
<property name="enrollmentStatus"></property>
<property name="attendanceLevel"></property>
<property name="attendanceDays"></property>
<property name="authorizedAbsences"></property>
<property name="unexcusedAbsences"></property>
<property name="excusedAbsences"></property>
<property name="tardies"></property>
<property name="attendancePct"></property>
</class>
<sql-query name="attendanceDetailsBySchoolAndGradingPeriod">
<return alias="attSchGr" class="edu.kdc.visioncards.pojo.AttendanceBreakDown">
<return-property name="studentName" column="student_name"/>
<return-property name="pupilId" column="student_id"/>
<return-property name="enrollmentStatus" column="enrollment_status"/>
<return-property name="attendanceLevel" column="attendance_Level"/>
<return-property name="attendanceDays" column="attendance_days"/>
<return-property name="authorizedAbsences" column="auth_abs"/>
<return-property name="unexcusedAbsences" column="unx_abs"/>
<return-property name="excusedAbsences" column="x_abs"/>
<return-property name="tardies" column="tardies"/>
<return-property name="attendancePct" column="att_pct"/>
</return>
select
a.student_name
,a.student_id
,a.enrollment_status
,a.attendance_days
,a.Attendance_Level
,b.authorized_absences as auth_abs
,nvl(c.unx_abs,0) as unx_abs
,nvl(d.x_abs, 0) as x_abs
,nvl(e.tardies, 0) as tardies
,a.att_pct
from
(select
s.student_name
,s.student_id
,s.student_activity_indicator as enrollment_status
,sum(fas.attendance_days) as attendance_days
,round((sum(fas.attendance_value) / sum(fas.attendance_days))* 100,2) as att_pct
,case when(round((sum(fas.attendance_value) / sum(fas.attendance_days))* 100,2) <= 87)
then 'Intervene'
when(round((sum(fas.attendance_value) / sum(fas.attendance_days))* 100,2) >87 and
round((sum(fas.attendance_value) / sum(fas.attendance_days))* 100,2) <= 89.9)
then 'Concern'
when(round((sum(fas.attendance_value) / sum(fas.attendance_days))* 100,2) >=90 and
round((sum(fas.attendance_value) / sum(fas.attendance_days))* 100,2) <= 95)
then 'Baseline'
else 'Is Clean'
end AS Attendance_Level
from K12INTEL_DW.ftbl_attendance_stumonabssum fas
inner join k12intel_dw.dtbl_students s
on fas.student_key = s.student_key
inner join K12INTEL_DW.dtbl_schools ds
on fas.school_key = ds.school_key
inner join k12intel_dw.dtbl_school_dates dsd
on fas.school_dates_key = dsd.school_dates_key
where dsd.rolling_local_school_yr_number = 0
and ds.school_code = ?
and s.student_activity_indicator = 'Active'
and fas.LOCAL_GRADING_PERIOD = ?
and s.student_current_grade_level = ?
group by s.student_id, s.student_name, s.student_activity_indicator
having (sum(fas.attendance_value) / sum(fas.attendance_days)) < .95
) a
inner join
(select t.student_id
,sum(t.auth_abs) as authorized_absences
from(
select dstud.student_id
,case when(fas.excused_authorized) in ('NA', 'No')
then 0 else 1
end as auth_abs
from K12INTEL_DW.ftbl_attendance_stumonabssum fas
inner join K12INTEL_DW.dtbl_schools ds
on fas.school_key = ds.school_key
inner join k12intel_dw.dtbl_students dstud
on dstud.student_key = fas.student_key
inner join k12intel_dw.dtbl_school_dates dsd
on dsd.school_dates_key = fas.school_dates_key
where dsd.rolling_local_school_yr_number = 0
and dstud.student_activity_indicator = 'Active'
and ds.school_code = ?
and fas.LOCAL_GRADING_PERIOD = ?
and dstud.student_current_grade_level = ?
) t
group by t.student_id)b
on b.student_id = a.student_id
left outer join
( select dstud.student_id,
count(fas.excused_absence) as unx_abs
from K12INTEL_DW.ftbl_attendance_stumonabssum fas
inner join K12INTEL_DW.dtbl_schools ds
on fas.school_key = ds.school_key
inner join k12intel_dw.dtbl_students dstud
on dstud.student_key = fas.student_key
inner join k12intel_dw.dtbl_school_dates dsd
on dsd.school_dates_key = fas.school_dates_key
where dsd.rolling_local_school_yr_number = 0
and dstud.student_activity_indicator = 'Active'
and fas.excused_absence = 'Un-excused absence'
and ds.school_code = ?
and fas.LOCAL_GRADING_PERIOD = ?
and dstud.student_current_grade_level = ?
group by dstud.student_id
) c
on c.student_id = a.student_id
left outer join
(select dstud.student_id, count(fas.excused_absence) as x_abs
from K12INTEL_DW.ftbl_attendance_stumonabssum fas
inner join K12INTEL_DW.dtbl_schools ds
on fas.school_key = ds.school_key
inner join k12intel_dw.dtbl_students dstud
on dstud.student_key = fas.student_key
inner join k12intel_dw.dtbl_school_dates dsd
on dsd.school_dates_key = fas.school_dates_key
where dsd.rolling_local_school_yr_number = 0
and dstud.student_activity_indicator = 'Active'
and fas.excused_absence = 'Excused absence'
and ds.school_code = ?
and fas.LOCAL_GRADING_PERIOD = ?
and dstud.student_current_grade_level = ?
group by dstud.student_id) d
on d.student_id = a.student_id
left outer join
(select s.student_id
,sum(a.attendance_value) tardies
from k12intel_dw.ftbl_attendance a
inner join k12intel_dw.dtbl_school_dates sd
on a.school_dates_key = sd.school_dates_key
inner join k12intel_dw.dtbl_students s
on a.student_key = s.student_key
inner join k12intel_dw.dtbl_schools sc
on sc.school_key = s.school_key
where 1=1
and sd.rolling_local_school_yr_number = 0
and a.attendance_type in ('LA','LP','LF')
and sc.school_code= ?
and s.student_current_grade_level = ?
group by s.student_id) e
on e.student_id = a.student_id
</sql-query>
</hibernate-mapping>
Este es mi dao:
@Repository
public class K12DaoImpl implements K12DaoManager{
@PersistenceContext
private EntityManager em;
// @Autowired
// private SessionFactory sessionFactory;
//
// public void setSessionFactory(SessionFactory sessionFactory) {
// this.sessionFactory = sessionFactory;
// }
@Override
@Transactional(readOnly = true)
public List<AttendanceBreakDown> getAttendanceBreakDownBySchoolAndGP(int school, String gradingPeriod, String gradeLevel) {
Object values[] = new Object[]{new Integer(school), gradingPeriod, gradeLevel,
new Integer(school), gradingPeriod, gradeLevel,
new Integer(school), gradingPeriod, gradeLevel,
new Integer(school), gradingPeriod, gradeLevel,
new Integer(school), gradeLevel
};
// Call Named Query through JPA
// Query query = em.createNamedQuery("attendanceDetailsBySchoolAndGradingPeriod");
//
// for (int i = 0; i < values.length; i++) {
// query.setParameter(i, values[i]);
// }
//
// List<AttendanceBreakDown> list = query.getResultList();
//
// Call Named Query through Hibernate's SessionFactory
// org.hibernate.Query query = sessionFactory.getCurrentSession().getNamedQuery("attendanceDetailsBySchoolAndGradingPeriod");
//
// for (int i = 0; i < values.length; i++) {
// query.setParameter(i, values[i]);
// }
//
// List<AttendanceBreakDown> list = query.list();
//Call Named Query through HibernateTemplate
//List<AttendanceBreakDown> list = getHibernateTemplate().findByNamedQuery("attendanceDetailsBySchoolAndGradingPeriod", values);
//return list;
return null;
}
}
Antes, sin usar Persistence.xml tenía la configuración típica de hibernate.cfg.xml dentro de una aplicación-DataSource con it Factory, la fábrica de sesión vinculada a la fuente de datos, etc. y todo funciona bien.
Ahora tengo Persistence.xml, no más SessionFactory, EntityManager ahora.
¿Cómo puedo cargar archivos HBM.XML y ejecutarlos a través de Hibernate en lugar de a través de JPA 2.0?
Si ve el código comentado en el DAO si estaba usando una configuración de Hibernate llamando a la consulta nombrada a través de HibernateTemplate (extender HibernatedaSupport) estaba funcionando. ¿Cómo sería el código ahora?
Gracias
Solución
He encontrado la respuesta a mi propia pregunta. Para que funcione, esto es lo que he hecho:
Usar u003Cmapping-file>... hbm.xmlu003C/mapping-file> en el interior u003Cpersistence-unit> en persistencia.xml. Realmente no tenía el uso del u003Cmapping-file>... hbm.xmlu003C/mapping-file> Etiqueta, ya que eso me estaba dando todo tipo de excepciones, una de ellas fue DuplicatEppingException. Según los documentos, también pensé que tenía que usar esa etiqueta, pero resulta que no es necesario.Creado edu/kdc/visioncards/pojo/asstitancebreakdown.hbm.xml por debajo src/main/recursos
Finalmente en mi Dao, Tengo lo siguiente:
@Override @Transactional(readOnly = true) public List<AttendanceBreakDown> getAttendanceBreakDownBySchoolAndGP(int school, String gradingPeriod, String gradeLevel) { Object values[] = new Object[]{new Integer(school), gradingPeriod, gradeLevel, new Integer(school), gradingPeriod, gradeLevel, new Integer(school), gradingPeriod, gradeLevel, new Integer(school), gradingPeriod, gradeLevel, new Integer(school), gradeLevel }; org.hibernate.Session session = (Session) em.getDelegate(); org.hibernate.Query query = session.getNamedQuery("attendanceDetailsBySchoolAndGradingPeriod"); for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } List<AttendanceBreakDown> list = query.list(); return list; }
Ahora puedo usar JPA 2.0 a través de EntityManager y bajar a la sesión de Hibernate para tener acceso a todas las características de Hibernate que JPA 2.0 no ofrece.