我刚刚使用Hibernate作为JPA2.0提供程序启动了一个Spring Roo应用程序。我使用的jar如下:
hibernate-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
我正在使用注释来处理应用程序的事务方面,在那里没有问题。
但是应用程序的其他部分需要非常复杂的查询,而我之前在Hibernate中处理过的方式是创建一个映射文件,例如(mybigdwquery.hbm.xml),我将在其中指定查询及其映射对象,即POJO。不是@Entity。这很好。
但是,通过我先前发布的另一个问题,我发现在JPA 2.0中,您不能将查询映射到POJO,所有内容都必须映射到@Entity(数据库表不是吗?)。
所以我的问题如下:
有什么办法可以将我的 “ mybigdwquery.hbm.xml” 文件作为hbm.xml加载到我的persistence.xml中,以便调用命名查询?
我的persistence.xml如下:
<?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>
我需要加载的文件:
<?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>
这是我的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; } }
以前,在不使用persistence.xml的情况下,我在applicationContext- datasource中使用会话工厂,与数据源绑定的会话工厂等进行了典型的hibernate.cfg.xml设置。一切正常。
现在我有了persistence.xml,现在没有更多的SessionFactory和EntityManager。
如何加载hbm.xml文件并通过Hibernate而非JPA 2.0执行它们?
如果您在DAO中看到注释的代码如果我使用的是Hibernate配置,则通过HibernateTemplate调用命名查询(扩展了HibernateDaoSupport)正在工作。现在的代码是什么样的?
谢谢
我找到了自己问题的答案。为了使它起作用,这就是我所做的:
在 persistence.xml的* < persistence-unit>内使用 < mapping-file> … hbm.xml mapping-file> ***。 我真的没有使用 < mapping-file> … hbm.xml mapping-file>标记,因为这给了我各种各样的异常,其中之一就是DuplicateMappingException。根据文档,我还认为我必须使用该标签,但事实证明您不必这样做。
在 src / main / resources* 下创建了 edu / kdc / visioncards / pojo / AttendanceBreakDown.hbm.xml *
最后,在我的 DAO中 ,我具有以下内容:
@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; }
现在,我可以通过EntityManager使用JPA 2.0,并跳到Hibernate的Session来访问JPA 2.0不提供的所有Hibernate功能。