【问题标题】:Paramertized Native Query returning empty resultset [parameter as comma separated string] (Using JPA)返回空结果集的参数化本机查询[参数为逗号分隔字符串](使用 JPA)
【发布时间】:2017-02-03 11:01:04
【问题描述】:

我正在尝试使用 JPA 2.0 执行本机查询。我在 orm.xml 中定义了我的本机查询

 Orm.xml
    <named-native-query name="getAgencyUsersByRoles">
        <query><![CDATA[SELECT DISTINCT a1.USR_LOGIN,c.PERSON_FIRST_NAME,c.PERSON_LAST_NAME,a1.EMAIL, b.auth_role_code FROM USERS a1,PERSON_AUTH_ROLES b,PERSON c WHERE ((b.group_code = 'RCATAG' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN (?)) OR (b.group_code = 'RCEMP' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN (?) ) ) AND a1.email IS NOT NULL AND a1.status in ('ACTIVE','PASSWORD EXPIRED')  ORDER BY a1.usr_login]]></query>
    </named-native-query>

我使用 jpa 执行查询的代码。

    Query query = getEntityManager()
            .createNamedQuery(NotificationPersistenceConstants.GET_AGENCY_USERS_BY_ROLES);
    query.setParameter(1, roles);
    query.setParameter(2, cccRoles);
    // fetch the results
    List<Object[]> list = query.getResultList();

此查询在执行时不会引发任何异常我验证了我的应用程序的 jpa 日志但返回给我空结果集。

当我在我的数据库服务器中触发相同的查询时,我得到的结果集证明我的查询没有问题,并且表还保存了针对该查询返回的记录。

我试图打破我的本机查询并简单地将它们作为单独的本机查询执行我在查询中拥有的所有表。 下面是我尝试使用 DISTINCT 子句来检查 DISTINCT 关键字是否是罪魁祸首。但他们都工作得很好,并在List&lt;Object[]&gt; 下给出了结果

SELECT DISTINCT a1.USR_LOGIN FROM USERS a1 ORDER BY a1.usr_login
SELECT DISTINCT b.auth_role_code FROM PERSON_AUTH_ROLES b
SELECT DISTINCT c.PERSON_LAST_NAME FROM PERSON c

更新了我在查询中传递的角色和 cccRoles 查询参数。

roles = 'teller','lender','bacth',etc... // This list is dynamically created at runtime
cccRoles = 'cccadmin','ccuser',etc // This list is dynamically created at runtime

现在我不确定是什么问题。

查询? - 不应该像我验证的那样直接在数据库服务器中运行相同的查询并且运行良好。

实体管理器(JPA)? - 验证所有配置并执行上述个别查询并返回结果。

加入?...

如果有人在使用 WAS 8.5、JPA 2.0 时遇到同样的问题,请帮助我。

【问题讨论】:

  • 尝试跟踪查询。即:alter session set events '10046 trace name context forever , level 12';

标签: java oracle jpa jpa-2.0 nativequery


【解决方案1】:

好的,我能够深入了解我的问题,发现问题出在我设置查询对象的参数上。

罪魁祸首代码行:

String roles = 'teller','lender','bacth';// This list is dynamically created at runtime of nth elements
Strign cccRoles = 'cccadmin','ccuser';// This list is dynamically created at runtime of nth elements
Query query = getEntityManager().createNamedQuery(NotificationPersistenceConstants.GET_AGENCY_USERS_BY_ROLES);
query.setParameter(1,roles);
query.setParameter(1,cccRoles);

在我上面的代码中,rolescccRoles 字符串被替换为单个 ?我的查询字符串中的占位符,因此当查询被解释为查找时,整个字符串(即'teller','lender','bacth')与提到的列b.auth_role_code匹配,与数据库中的每个数据库记录相匹配,因此它没有发现任何针对它的记录。

然而,如果我通过在查询中直接替换此字符串参数(rolescccRoles)在 java 中构建相同的查询字符串,然后调用 createNativeQuery(),它的工作方式类似于:

Query query = getEntityManager().createNativeQuery("SELECT DISTINCT a1.USR_LOGIN,c.PERSON_FIRST_NAME,c.PERSON_LAST_NAME,a1.EMAIL, b.auth_role_code FROM USERS a1,PERSON_AUTH_ROLES b,PERSON c WHERE ((b.group_code = 'RCATAG' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN ('teller','lender','bacth')) OR (b.group_code = 'RCEMP' and a1.person_id=b.person_id and b.person_id=c.person_id AND b.auth_role_code IN ('cccadmin','ccuser') ) ) AND a1.email IS NOT NULL AND a1.status in ('ACTIVE','PASSWORD EXPIRED')  ORDER BY a1.usr_login");

底线:只要在Query 对象中使用setParameter 在sql 查询中发生?(placeholder) 的替换,即使传递的参数字符串以逗号分隔,它也会映射为单个列值.

但是当通过直接连接参数字符串(不使用setParameter)在java中构建相同的查询然后执行时,它会起作用并将其视为要查找的字符串列表。

此类情况的可能解决方案:

  • 替换并构建连接所有此类动态字符串参数列表的完整查询。(不使用setParameter())并使用createNativeQuery() 执行
  • 使用 JPA 提供者的 Criteria Builder API 并构建查询然后执行。 (推荐)
  • 构建所需的编号。 ?(placeholders) 基于我们列表的大小,然后调用等效编号。循环中的 setParameters。

  • ?? (任何人有任何其他更好的解决方案请帮助。)

虽然我仍然试图得到一个答案,即在运行时在 java 中构建相同的查询字符串和调用 createNativeQuery 与使用 query.setParameter() 设置查询参数时有什么区别。

【讨论】:

  • 我也遇到过类似的问题。但它在早期版本中运行良好,在 Hibernate 5.3.xx 中运行,但在 5.4.x 中不运行。如果您有任何其他解决方案或 setParamter() 的替代方案,请发布。
【解决方案2】:

这可能是因为您在单个参数中传递了串联参数'teller','lender','bacth',因此在 jpa 中将其作为单个字符串参数进行比较。 因此它不返回任何结果。

【讨论】:

    猜你喜欢
    • 2012-05-11
    • 2019-10-04
    • 2016-10-01
    • 2012-03-23
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多