2014-10-30 60 views
0

我想將兩個參數傳遞給namedquery。一個是數字類型,另一個是字符串類型。他們都可能是空的。例如,(id = null,username ='joe')和(id = 1,username ='joe')是兩個不同的結果。在namedQuery中,如果id爲null,則語法爲「u.id is null」,但如果id不爲null,則爲「u.id =:id」。我的問題是如何動態處理namedQuery中的id字段?如何在JPA命名查詢中處理數字類型的空值

請檢查我的示例代碼:

1.User.java

@NamedQueries({ 
     @NamedQuery(name = "getUser", query = "select u from User u" 
       + " where u.id = :id"  
       + " And u.username= :username") 
}) 
public class User{ 
    public Long id; 
    public String username; 
} 
  • UserDao.java
  • public User getUser(Long id, String username) { 
        TypedQuery<User> query = Dao.entityManager.createNamedQuery("getUser", User.class); 
        query.setParameter("id", id); 
        query.setParameter("username", username); 
    
        List<User> users = query.getResultList(); 
    
        if (users.size() > 0) { 
         return users.get(0); 
        } else { 
         return null; 
        } 
    } 
    

    = ======================================

    我曾嘗試:

    1. 這是遺留代碼,我不想改變結構。所以我不想使用Criteria。

    2. 從用戶U其中選擇U(:id爲null或u.id =:ID)和u.username =:用戶名

      //拋出異常:不一致的數據類型:預期數量有BINARY

    3. 從用戶選擇U U其中u.id = NULLIF(:ID,NULL)和u.username =:用戶名

      //拋出異常:不一致的數據類型:預期數量有BINARY

    4. 我也嘗試過nvl和解碼namedQuery,不起作用。

    5. query.setParameter(「id」,id == null?-1:id)// did not work。

    我最後的選擇是在UserDao文件中寫入查詢來替換用戶文件中的namedQuery。

    謝謝!

    ===========================================

    我耗盡時間,不得不放棄使用namedQuery。我的解決辦法:

    # UserDao.java 
    
        public User getUser(Long id, String usename) { 
         String getUser = "select u from user u where u.id " + Dao.isNull(id) 
             + " And u.username " + Dao.isNull(username); 
         Query query = Dao.entityManager.createQuery(getUser); 
        } 
    
    # Dao.java 
    
        public static String isNull(Object field) { 
         if (field != null) { 
           if (field instanceof String) { 
            return " = " + "'" + field + "'"; 
           } else { 
            return " = " + field; 
           } 
    
          } else { 
           return " is NULL "; 
          } 
        } 
    
    +0

    你確定問題出在參數上嗎?除了這個空的問題,查詢的工作原理和返回正確的結果? – 2014-10-30 15:44:58

    +0

    不是,oracle不會將空字符串視爲空嗎? – zmf 2014-10-30 15:45:37

    +0

    是的。這是空的問題。代碼之前工作正常。我剛剛得到了這個問題,因爲我們想改變id字段可能爲空的要求。以前,id字段是非空的。 – Bryan 2014-10-30 15:49:07

    回答

    0

    如果)在查詢的結尾是一個錯誤,嘗試沒有它

    @NamedQuery(name = "getUser", query = "select u from User u" 
          + " where (:id is null or u.id = :id)"  
          + " And :username" 
    

    編輯

    如果一切都失敗了,這種快速的解決方法應該這樣做(如果您沒有數據庫中的負號)與上述空檢查結合使用

    query.setParameter("id", id == null ? -1 : id); 
    
    +0

    謝謝你你的改正。那是我的錯字。該方法不起作用。 – Bryan 2014-10-30 15:34:09

    +0

    這是一個查詢,而不是一個java語句。 ':id is null'在查詢世界中沒有意義,因爲':id'是數據庫未知的變量。 – pms 2014-10-30 15:34:41

    +0

    @pmp它不是毫無意義的,它故意使用變量。像這樣的表達式的意思是,如果你傳遞'null'作爲參數值,'OR'的左側將被評估爲'true',所以右側將不被考慮。 – 2014-10-30 15:39:17

    3

    您不能在運行時更改命名查詢。這樣做會破壞指定查詢的目的。 動態查詢應該使用標準api創建。

    請參閱this回答在指定查詢中使用什麼。

    from CountryDTO c where 
        ((:status is null and c.status is null) or c.status = :status) 
        and c.type =:type 
    
    +0

    試過。拋出異常:ORA-00932:不一致的數據類型:期望的NUMBER得到BINARY – Bryan 2014-10-30 15:31:27