2011-12-02 6 views
5

Ho appena avviato un'applicazione Spring Roo con Hibernate come provider JPA2.0. Sto usando i barattoli come segue:Come caricare un file "xxx.hbm.cfg" di Hibernate in un progetto JPA 2.0?

hibernate-core-3.6.4.Final.jar

ibernazione-commons-annotazioni-3.2.0.jar

hibernate-EntityManager -3.6.4.Final.jar

hibernate-APP-2.0-api-1.0.0.Final.jar

hibernate-validatore-4.1.0.Final.jar

Sto usando annotazioni per gestire l'aspetto transazionale della domanda, nessun problema.

Ma ci sono altre parti dell'applicazione che richiedono query molto complesse e il modo in cui l'ho gestito in Hibernate prima era creare un file di mappatura es. (Mybigdwquery.hbm.xml) dove specificherò la mia query e il suo oggetto di mappatura, un POJO. Non un @Entity. Funziona bene

Tuttavia, tramite un'altra domanda che ho pubblicato in precedenza, ho scoperto che in JPA 2.0 non è possibile avere query mappate su un POJO, tutto deve essere mappato su un @Entity (un numero di tabella db?).

Quindi la mia domanda è la seguente:

C'è un modo che io possa avere la mia 'mybigdwquery.hbm.xml' file caricato nel mio persistence.xml come hbm.xml in modo che io può chiamare la query denominata?

mio persistence.xml è la seguente:

<?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> 

Il file che ho bisogno caricato:

<?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> 

Questo è il mio 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; 
    } 
} 

Prima, senza utilizzare la persistenza .xml Ho avuto le tipiche impostazioni hibernate.cfg.xml all'interno di un'applicazioneContext-datasource con la sua factory di sessione, la ses fabbrica sion legata all'origine dati ecc., tutto funziona bene.

Ora ho persistence.xml, non più SessionFactory, EntityManager ora.

Come caricare file hbm.xml ed eseguirli tramite Hibernate anziché tramite JPA 2.0?

Se si vede il codice commentato nel DAO Se stavo usando una configurazione di Hibernate che chiama la query denominata tramite HibernateTemplate (estensione di HibernateDaoSupport) funzionava. Come sarebbe il codice ora?

Grazie

risposta

3

ho trovato la risposta alla mia domanda.Per farlo funzionare questo è quello che ho fatto:

  1. Usa < mapping-file> ... hbm.xml </mapping-file> all'interno < persistenza a unità> in persistenza .xml . Non ho davvero utilizzato il tag mapping-file> ... hbm.xml </mapping-file>, poiché questo mi ha fornito ogni sorta di eccezione, tra cui DuplicateMappingException. Secondo i documenti ho anche pensato che dovevo usare quel tag, ma si scopre che non è necessario.

  2. creati edu/KDC/visioncards/POJO/AttendanceBreakDown.hbm.xml sotto src/main/risorse

  3. Infine nel mio DAO, ho come segue:

    @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; 
    } 
    

ora posso usare JPA 2.0 attraverso EntityManager e scendere alla sessione di Hibernate per avere accesso a tutti H Funzioni di ibernate che JPA 2.0 non offre.

+1

OK, vedo. Ero curioso e la tua risposta mi ha confuso. Quindi penso che avere un file .hbm.xml con lo stesso pacchetto e nome di @Entity sia sufficiente per essere raccolto da Hibernate EntityManager. – greyfairer

Problemi correlati