簡體   English   中英

參數化的本機查詢返回空結果集[參數為逗號分隔的字符串](使用JPA)

[英]Paramertized Native Query returning empty resultset [parameter as comma separated string] (Using JPA)

我正在嘗試使用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<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

現在我不確定是什么問題。

查詢? -不應該是因為我驗證了直接在DB服務器中運行相同的查詢並且運行良好。

EntityManager(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);

在我上面的代碼中, rolescccRoles字符串已替換為單個字符串? 我查詢字符串中的占位符,因此當解釋查詢以查找時,整個字符串(即“ teller”,“ lender”,“ bacth”)與提到的列b.auth_role_code與數據庫中的每個數據庫記錄進行匹配,因此它沒有找到任何反對的記錄。

而如果我要通過直接在查詢中替換此字符串參數( rolescccRoles )然后調用createNativeQuery()來在Java中構建相同的查詢字符串,則其工作原理類似於:

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查詢中使用Query對象中的setParameter替換?(placeholder)時,即使傳遞的參數字符串用逗號分隔,它也會映射為單列值。

但是,當在Java中通過直接串聯參數字符串(不使用setParameter)然后執行該查詢時,它將起作用並將其視為要查找的字符串列表。

此類情況的可能解決方案:

  • 替換並構建將所有此類動態字符串參數列表連接在一起的完整查詢。(不使用setParameter() )和使用createNativeQuery()執行
  • 使用JPA提供程序的Criteria Builder API並生成查詢,然后執行。 (推薦的)
  • 需要構建 基於列表大小的?(placeholders) ,然后調用等號。 setParameters在循環中。

  • ?? (任何其他人都可以針對這種情況提供其他更好的解決方案。)

盡管我仍然試圖獲得關於在Java運行時構建相同查詢字符串與調用createNativeQuery與使用query.setParameter()設置查詢參數時的區別之間的區別的答案。

這可能是因為您在單個參數中傳遞了連接的參數'teller','lender','bacth' ,因此在jpa中將其作為單個字符串參數進行比較。 因此,它不返回任何結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM