2011-12-02 15 views
5

Acabo de iniciar una aplicación Spring Roo con Hibernate como proveedor JPA2.0. Estoy usando los frascos de la siguiente manera:Cómo cargar un archivo Hibernate 'xxx.hbm.cfg' en un proyecto JPA 2.0?

hibernación-core-3.6.4.Final.jar

hibernar-commons-anotaciones-3.2.0.jar

hibernación-EntityManager -3.6.4.Final.jar

hibernación-JPA-2,0-api-1.0.0.Final.jar

hibernación-validador-4.1.0.Final.jar

estoy usando anotaciones para manejar el aspecto transaccional de la aplicación, no hay problema.

Pero hay otras partes de la aplicación que requieren consultas muy complejas, y la forma en que lo manejé en Hibernate antes era crear un archivo de asignación, por ejemplo (mybigdwquery.hbm.xml) donde especificaría mi consulta y su objeto de mapeo, un POJO. No es un @Entity. Esto funciona bien

Sin embargo, a través de otra pregunta que publiqué anteriormente, descubrí que en JPA 2.0 no puede haber consultas asignadas a un POJO, todo tiene que estar correlacionado con una @Entidad (¿una tabla db no?).

Así que mi pregunta es la siguiente:

¿Hay alguna manera de que puedo tener mi 'mybigdwquery.hbm.xml' archivo cargado en mi persistence.xml como hbm.xml para que yo puede llamar a la consulta nombrada?

Mi persistence.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 cargado:

<?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) &lt;= 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) &lt;= 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) &lt;= 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)) &lt; .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> 

Ésta 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 necesidad de utilizar la persistencia .xml Tenía las configuraciones hibernate.cfg.xml típicas dentro de una applicationContext-datasource con la fábrica de sesiones, las sesiones La fábrica de Sion está ligada a la fuente de datos, etc. y todo funciona bien.

Ahora tengo persistence.xml, no hay 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 utilizando una configuración de Hibernate llamando a la consulta con nombre a través de la HibernateTemplate (se extiende HibernateDaoSupport) estaba trabajando. ¿Cómo sería el código ahora?

Gracias

Respuesta

3

He encontrado la respuesta a mi pregunta.Para que funcione esto es lo que he hecho:

  1. Uso < mapeo-file> ... hbm.xml </mapeo-file> dentro < persistence-unit> en persistencia .xml . Realmente no tenía el uso del < mapeo-archivo> ... hbm.xml </mapeo-archivo> etiqueta, ya que me daba todo tipo de excepciones, una de ellas era DuplicateMappingException. De acuerdo con los documentos, también pensé que tenía que usar esa etiqueta, pero resulta que no es necesario.

  2. Creado edu/KDC/visioncards/POJO/AttendanceBreakDown.hbm.xml bajo src/main/resources

  3. último en mi DAO, que tienen la siguiente manera:

    @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 H características de seguridad que JPA 2.0 no ofrece.

+1

Bien, ya veo. Tenía curiosidad sobre eso, y tu propia respuesta me confundió. Así que supongo que tener un archivo .hbm.xml con el mismo paquete y nombre que su @Entity es suficiente para que Hibernate EntityManager lo recoja. – greyfairer

Cuestiones relacionadas