2010-03-05 64 views
0

我的原生查詢正在工作正常oracle sqlplus。但通過JPA本機查詢,從而以下錯誤:JPA + Hibernate +原生查詢+結果集中的dtos自定義列表

[錯誤] org.hibernate.util.JDBCExceptionReporter - ORA-00923:FROM關鍵字未找到預期

原生查詢


SELECT sch.school_name, term.term_name, count(material.MATERIAL_ID), sip.SIP_COUNT, ... FROM VA_SCHOOL sch JOIN va_user_school_rel usr1 on sch.school_id=usr1.school_id 

JOIN va_user ur ON usr1.USER_ID= ur.USER_ID 
JOIN va_user_role_rel urr1 on usr1.user_id=urr1.user_id 
JOIN va_role rle ON urr1.role_id= rle.role_id 
JOIN va_user_school_rel usr2 on sch.school_id=usr2.school_id 
JOIN va_user ur1 ON usr2.USER_ID= ur1.USER_ID 
JOIN va_user_role_rel urr2 on usr2.user_id=urr2.user_id 
JOIN va_role rle1 ON urr2.role_id= rle1.role_id 
JOIN va_term term on term.school_id = usr1.school_id 
JOIN va_class course on course.term_id = term.term_id 
JOIN va_material material on material.class_id = course.class_id 
LEFT JOIN (SELECT VA_CLASS.TERM_ID TERM_ID, COUNT(*) as SIP_COUNT FROM VA_CLASS JOIN VA_MATERIAL ON VA_MATERIAL.CLASS_ID = VA_CLASS.CLASS_ID WHERE VA_CLASS.reference_flag = 'A' AND trunc(VA_MATERIAL.SCHOOL_STATUS) = 0 GROUP BY VA_CLASS.TERM_ID) sip on term.term_id = sip.term_id 

WHERE course.reference_flag = 'A' AND rle.role_name='ROLE_1' AND rle1.role_name='ROLE_2' 

GROUP BY sch.school_name, term.term_name, sip.SIP_COUNT 
ORDER BY sch.school_name, term.term_name 

JPA原生查詢:


SELECT new MyDTO(sch.school_name, term.term_name, count(material.MATERIAL_ID), sip.SIP_COUNT, ...) FROM VA_SCHOOL sch 
JOIN va_user_school_rel usr1 on sch.school_id=usr1.school_id 
JOIN va_user ur ON usr1.USER_ID= ur.USER_ID 
JOIN va_user_role_rel urr1 on usr1.user_id=urr1.user_id 
JOIN va_role rle ON urr1.role_id= rle.role_id 
JOIN va_user_school_rel usr2 on sch.school_id=usr2.school_id 
JOIN va_user ur1 ON usr2.USER_ID= ur1.USER_ID 
JOIN va_user_role_rel urr2 on usr2.user_id=urr2.user_id 
JOIN va_role rle1 ON urr2.role_id= rle1.role_id 
JOIN va_term term on term.school_id = usr1.school_id 
JOIN va_class course on course.term_id = term.term_id 
JOIN va_material material on material.class_id = course.class_id 

LEFT JOIN (SELECT VA_CLASS.TERM_ID TERM_ID, COUNT(*) as SIP_COUNT FROM VA_CLASS JOIN VA_MATERIAL ON VA_MATERIAL.CLASS_ID = VA_CLASS.CLASS_ID WHERE VA_CLASS.reference_flag = 'A' AND trunc(VA_MATERIAL.SCHOOL_STATUS) = 0 GROUP BY VA_CLASS.TERM_ID) sip on term.term_id = sip.term_id 

WHERE course.reference_flag = 'A' AND rle.role_name=:p_roleName AND rle1.role_name=:p_roleName1 

GROUP BY sch.school_name, term.term_name, sip.SIP_COUNT 
ORDER BY sch.school_name, term.term_name 
+1

嘗試設置hibernate.show_sql = true以查看並檢查它生成的原始SQL。這可能會有所幫助。 – 2010-03-05 16:21:02

回答

0

JPA本機查詢不會改變結果集爲提供的類型DTO的列表:(。我們需要明確的做。

感謝,
斯里裏

+0

我不知道它是否適合您,但如果您不想在代碼中執行映射並將其委託給JPA,則可能使用SqlResultSetMapping。 – snowflake 2010-03-08 13:30:20

+0

使用SqlResultSetMapping-可以將數據僅轉換爲實體。但要轉換成自定義DTO,應該明確地使用JPA本機查詢 – Srihari 2010-03-09 12:03:58

0

看看this question的答案。確認驗證查詢是一樣的東西SELECT 1 FROM DUAL;

0

一JPA本地查詢意味着,它是直接的sql。new MyDTO(...)不是SQL,因此sql解析器會拒絕它。 您必須提供一個映射到結果集的實體,最簡單的方法是使用@SqlResultSetMapping,然後引用到你的查詢映射到 恕我直言,使用@NamedNativeQuery like

@SqlResultSetMapping(
    name="yourResultSetMapping", 
    entities = { 
     @EntityResult(
      entityClass=YourResultSetEntity.class, 
      fields = { 
       @FieldResult(name = "<entity class field name", column = "result set column name"), 
       . 
       . 
      } 
     ) 
    } 
) 

@NamedNativeQuery(
    name="getSchoolName", 
    query = "<your very long query here", 
    resultSetMapping = "yourResultMapping" 
) 

當心名稱衝突。如果結果集中有多個相同名稱的列,則JPA將無法解析它們,並且會發生異常。在結果集中使用別名爲每列賦予唯一名稱,並在@FieldResult的列部分使用別名。