2011-12-02 17 views
5

Właśnie rozpocząłem aplikację Spring Roo z Hibernate jako dostawcą JPA2.0. Używam słoiki następująco:Jak załadować plik "hibernate" xxx.hbm.cfg w projekcie JPA 2.0?

hibernate-core-3.6.4.Final.jar

hibernate-Commons adnotacje-3.2.0.jar

hibernacji-EntityManager -3.6.4.Final.jar

hibernacji, JPA-2,0-api 1.0.0.Final.jar

hibernacji-validator-4.1.0.Final.jar

używam adnotacje do obsługi transakcyjnej aspekt zastosowania, nie ma problemu.

Są jednak inne części aplikacji, które wymagają bardzo złożonych zapytań, a sposób, w jaki wcześniej miałem do czynienia z Hibernate, polegał na utworzeniu pliku odwzorowania, np. (Mybigdwquery.hbm.xml), w którym chciałbym podać moje zapytanie i jego obiekt odwzorowujący, POJO. Nie jest to @Entity. To działa dobrze.

Jednak za pomocą innego pytania, które wcześniej wysłałem, dowiedziałem się, że w JPA 2.0 nie można mieć kwerend mapowanych na POJO, wszystko musi być zmapowane do @Entity (a db table no?).

Więc moje pytanie brzmi następująco:

Czy istnieje jakiś sposób, że może mam „mybigdwquery.hbm.xml” plik załadowany w moim persistence.xml jako hbm.xml abym można wywołać określone zapytanie?

Moja persistence.xml jest następujący:

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

pliku, który muszę załadowany:

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

To mój 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; 
    } 
} 

Wcześniej bez użycia wytrwałości .xml Miałem typowe ustawienia hibernate.cfg.xml w źródle danych aplikacjiContext z fabryką sesji, ses fabryka sionowa związana ze źródłem danych itp. wszystko działa dobrze.

Teraz mam persistence.xml, nie więcej SessionFactory, EntityManager teraz.

Jak mogę załadować pliki hbm.xml i wykonać je przez Hibernate zamiast przez JPA 2.0?

Jeśli zobaczysz skomentowany kod w DAO Jeśli korzystałem z konfiguracji Hibernate wywoływanie nazwanego zapytania przez HibernateTemplate (rozszerzenie HibernateDaoSupport) działało. Jaki byłby teraz kod?

Dzięki

Odpowiedz

3

Znalazłem odpowiedź na moje własne pytanie.Aby to działało to co mam zrobić:

  1. Zastosowanie < mapping-file> ... hbm.xml </mapping-file> wewnątrz < trwałości jednostce> w wytrwałości .xml . Naprawdę nie miałem możliwości użycia pliku < mapping-file> ... hbm.xml </mapping-file>, ponieważ dawało mi to wszelkiego rodzaju wyjątki, jednym z nich był DuplicateMappingException. Według dokumentów myślałem także, że muszę użyć tego znacznika, ale okazuje się, że nie musisz.

  2. Utworzony edu/KDC/visioncards/POJO/AttendanceBreakDown.hbm.xml pod src/main/resources

  3. Wreszcie w moim DAO, mam następujący sposób:

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

Teraz mogę używać JPA 2.0 poprzez EntityManager i przejść do sesji Hibernate, aby uzyskać dostęp do wszystkich H Funkcje ibernate, których nie oferuje JPA 2.0.

+1

OK, rozumiem. Ciekawiło mnie to, a twoja własna odpowiedź mnie zdezorientowała. Domyślam się, że posiadanie pliku .hbm.xml z tym samym pakietem i nazwą, co @Entity, jest wystarczające, aby mogło zostać pobrane przez aplikację Hibernate EntityManager. – greyfairer