返回空结果集的参数化本机查询 [参数为逗号分隔字符串](使用 JPA)
Paramertized Native Query returning empty resultset [parameter as comma separated string] (Using JPA)
我正在尝试使用 JPA 2 执行本机查询。0.I 已在 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 日志但是return我的结果集是空的。
当我在我的数据库服务器中触发相同的查询时,我得到的结果集证明我的查询没有问题,而且 table 将针对此查询的记录保存到 return。
我试图打破我的本机查询,并简单地将它们作为单独的本机查询执行,用于查询中的所有 tables。
下面是我尝试使用 DISTINCT 子句来检查 DISTINCT 关键字是否是罪魁祸首。但他们都工作得很好并且在 List<Object[]>
下给出了结果
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 时遇到同样的问题,请帮助我。
好的,我能够深入了解我的问题,发现问题出在我设置查询对象的参数上。
罪魁祸首的代码行:
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);
在我上面的代码中,roles
& cccRoles
字符串被替换为单个 ?我的查询字符串中的占位符,因此当查询被解释为查找时,整个字符串(即 'teller'、'lender'、'bacth')与提到的列 b.auth_role_code
匹配数据库中的每个数据库记录,因此它没有找到任何针对它的记录。
然而,如果我通过在查询中直接替换此字符串参数 (roles
& cccRoles
) 在 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)
基于我们的 List 的大小,然后调用等价的 no。循环中的 setParameters.
?? (任何人对这种情况有任何其他更好的解决方案请帮助。)
虽然我仍然试图回答在 java 中在运行时构建相同的查询字符串和调用 createNativeQuery 与使用 query.setParameter 设置查询参数时有什么区别( ).
这可能是因为您在单个参数中传递了串联参数 'teller','lender','bacth'
,因此在 jpa 中将其作为单个字符串参数进行比较。
因此 returns 没有结果。
我正在尝试使用 JPA 2 执行本机查询。0.I 已在 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 日志但是return我的结果集是空的。
当我在我的数据库服务器中触发相同的查询时,我得到的结果集证明我的查询没有问题,而且 table 将针对此查询的记录保存到 return。
我试图打破我的本机查询,并简单地将它们作为单独的本机查询执行,用于查询中的所有 tables。
下面是我尝试使用 DISTINCT 子句来检查 DISTINCT 关键字是否是罪魁祸首。但他们都工作得很好并且在 List<Object[]>
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 时遇到同样的问题,请帮助我。
好的,我能够深入了解我的问题,发现问题出在我设置查询对象的参数上。
罪魁祸首的代码行:
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);
在我上面的代码中,roles
& cccRoles
字符串被替换为单个 ?我的查询字符串中的占位符,因此当查询被解释为查找时,整个字符串(即 'teller'、'lender'、'bacth')与提到的列 b.auth_role_code
匹配数据库中的每个数据库记录,因此它没有找到任何针对它的记录。
然而,如果我通过在查询中直接替换此字符串参数 (roles
& cccRoles
) 在 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)
基于我们的 List 的大小,然后调用等价的 no。循环中的 setParameters.?? (任何人对这种情况有任何其他更好的解决方案请帮助。)
虽然我仍然试图回答在 java 中在运行时构建相同的查询字符串和调用 createNativeQuery 与使用 query.setParameter 设置查询参数时有什么区别( ).
这可能是因为您在单个参数中传递了串联参数 'teller','lender','bacth'
,因此在 jpa 中将其作为单个字符串参数进行比较。
因此 returns 没有结果。