【问题标题】:JPA + Hibernate + Native Query + custom list of dtos from the resultsetJPA + Hibernate + Native Query + 结果集中的自定义 dto 列表
【发布时间】:2010-03-05 14:04:28
【问题描述】:

我下面的本机查询运行良好 oracle sqlplus。但通过 JPA 原生查询,报错如下:

[错误] 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

【问题讨论】:

  • 尝试设置 hibernate.show_sql=true 来查看和检查它生成的原始 SQL。这可能会有所帮助。

标签: hibernate jpa ora-00923


【解决方案1】:

看看this question的答案。验证验证查询类似于SELECT 1 FROM DUAL;

【讨论】:

    【解决方案2】:

    JPA 原生查询不会将结果集转换为提供的 DTO 类型列表 :(。我们需要明确地这样做。

    谢谢,
    斯里哈里

    【讨论】:

    • 我不知道它是否适合您,但如果您不想在代码中执行映射并将其委托给 JPA,也许您可​​以使用 SqlResultSetMapping。
    • 使用 SqlResultSetMapping- 只能将数据转换为实体。但是要转换为自定义 DTO,应该明确地进行,以防 JPA 原生查询
    【解决方案3】:

    JPA 原生查询就是这样,它是直接的 sql。 new MyDTO(...) 不是 SQL,因此 sql 解析器将拒绝它。 您必须提供一个映射到结果集的实体,最容易通过使用 @SqlResultSetMapping 然后在查询中引用该映射来完成。 恕我直言,使用 @NamedNativeQuery 之类的

    @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 的列部分中使用别名

    【讨论】:

      猜你喜欢
      • 2020-06-16
      • 1970-01-01
      • 2014-03-21
      • 2011-04-30
      • 2012-04-14
      • 2021-06-29
      • 2016-02-15
      • 2011-05-17
      • 2012-07-15
      相关资源
      最近更新 更多