Java 参数化本机查询返回空结果集[参数为逗号分隔字符串](使用JPA)

Java 参数化本机查询返回空结果集[参数为逗号分隔字符串](使用JPA),java,oracle,jpa,jpa-2.0,nativequery,Java,Oracle,Jpa,Jpa 2.0,Nativequery,我正在尝试使用JPA2.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

我正在尝试使用JPA2.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>
更新了我在查询中传递的roles&cccRoles查询参数

roles = 'teller','lender','bacth',etc... // This list is dynamically created at runtime
cccRoles = 'cccadmin','ccuser',etc // This list is dynamically created at runtime
现在我不确定是什么问题

查询?-不应该像我验证的那样,直接在DB服务器中运行相同的查询,并且效果良好

实体管理器(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);
在我上面的代码中,
角色
&
cccRoles
字符串被替换为单个?我的查询字符串中的占位符,因此当查询被解释为查找时,整个字符串(即“出纳员”、“出纳员”、“bacth”)与提到的列
b.auth\u role\u code
匹配数据库中的每个数据库记录,因此它没有找到任何与之对应的记录

然而,如果我在java中直接替换查询中的字符串参数(
roles
&
cccRoles
),然后调用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");
底线:在使用
查询
对象中的
设置参数
的sql查询中,每当发生
?(占位符)
的替代时,即使传递的参数字符串以逗号分隔,也会将其映射为单个列值

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

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

  • 替换并构建连接所有此类字符串参数动态列表的完整查询。(不使用
    setParameter()
    )并使用
    createNativeQuery()执行
  • 使用JPA provider的Criteria Builder API构建查询,然后执行。(推荐)
  • 根据列表的大小生成所需数量的
    ?(占位符)
    ,然后在循环中调用同等数量的setParameters

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


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

好的,我可以深入到我的问题,发现问题出在我设置查询对象的参数上

罪魁祸首代码行:

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);
在我上面的代码中,
角色
&
cccRoles
字符串被替换为单个?我的查询字符串中的占位符,因此当查询被解释为查找时,整个字符串(即“出纳员”、“出纳员”、“bacth”)与提到的列
b.auth\u role\u code
匹配数据库中的每个数据库记录,因此它没有找到任何与之对应的记录

然而,如果我在java中直接替换查询中的字符串参数(
roles
&
cccRoles
),然后调用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");
底线:在使用
查询
对象中的
设置参数
的sql查询中,每当发生
?(占位符)
的替代时,即使传递的参数字符串以逗号分隔,也会将其映射为单个列值

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

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

  • 替换并构建连接所有此类字符串参数动态列表的完整查询。(不使用
    setParameter()
    )并使用
    createNativeQuery()执行
  • 使用JPA provider的Criteria Builder API构建查询,然后执行。(推荐)
  • 根据列表的大小生成所需数量的
    ?(占位符)
    ,然后在循环中调用同等数量的setParameters

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


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

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

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

尝试跟踪查询。F.e.:
alter session set events'10046 trace name context forever,level 12'尝试跟踪查询。F.e.:
alter session set events'10046 trace name context forever,level 12'我也遇到了类似的问题。但它在早期版本中运行良好,在Hibernate 5.3.xx中工作,但在5.4.x中不工作。如果您有任何其他解决方案或setParameter()的替代方案,请发布。我也遇到了类似的问题。但它在早期版本中运行良好,在Hibernate 5.3.xx中工作,但在5.4.x中不工作。如果您对setParameter()有任何其他解决方案或替代方案,请发布。