Spring Data jpa findBy的使用和null值探索

近期在調用jpa框架中findById()進行查找對象時出現了Null value was assigned to a property of...錯誤,簡單來講就是null被賦予給某個屬性出錯,當時覺得是屬性沒賦予值出了錯誤,由於當我在mysql表記錄中插入相應值後,運行遍經過了,但後來網上搜索錯誤後發現是數據類型不一致才致使這個錯誤,研究代碼和表類型的時候發現那兩個報錯的屬性都是int型的數據,而沒有任何地方說明須要填充值,我就思考本身的想法出現了錯誤,把錯誤上網搜索後我終於發現一切都是null值的緣由。html

jpa中findBy函數查詢結果必定是整個對象的全部字段,想要某個字段,只能用List接受整個結果再去get(i)找到想要查找的字段,意思就是若是是User findById(),那麼返回的就是這個對應User的全部字段,關於[jpa]findBy的使用請跳轉java

https://blog.csdn.net/changningbuddha/article/details/77987236mysql

因此當須要返回全部字段就出錯了,由於有兩個int類型的屬性填入的值是null值(mysql中int類型的設置的默認值是null),那麼null究竟是什麼,爲何其餘許多類型賦予null不會報錯,而int型就出錯了。程序員

null是Java中一個很重要的概念。null設計初衷是爲了表示一些缺失的東西,例如缺失的用戶、資源或其餘東西。可是,後來實際使用時使人頭疼的空指針異常給Java程序員帶來很多的騷擾。下面是Java中null關鍵字的基本細節,而且探索一些技術來儘量的減小null的檢查以及如何避免噁心的空指針異常。sql

1)首先,null是關鍵字,像public、static、final。它是大小寫敏感的,你不能將null寫成Null或NULL,編譯器將不能識別它們而後報錯。數據庫

2)就像每種基本類型都有默認值同樣,如int默認值爲0,boolean的默認值爲false,null是任何引用類型的默認值,不嚴格的說是全部object類型的默認值。就像你建立了一個布爾類型的變量,它將false做爲本身的默認值,Java中的任何引用變量都將null做爲默認值。這對全部變量都是適用的,如成員變量、局部變量、實例變量、靜態變量(但當你使用一個沒有初始化的局部變量,編譯器會警告你)。爲了證實這個事實,你能夠經過建立一個變量而後打印它的值來觀察這個引用變量。數組

3)咱們要澄清一些誤解,null既不是對象也不是一種類型,它僅是一種特殊的值,你能夠將其賦予任何引用類型,你也能夠將null轉化成任何類型,來看下面的代碼:框架

String str =  null
Integer i =  null
Double d =  null ;  
 
String myStr = (String)  null
Integer myI = (Integer)  null ;
Double myD = (Double)  null
你能夠看到在編譯和運行時期,將null強制轉換成任何引用類型都是可行的,在運行時期都不會拋出空指針異常。

4)null能夠賦值給引用變量,但不能將null賦給基本類型變量,例如int、double、float、boolean。編譯器將會報錯。函數

正如你看到的那樣,當你直接將null賦值給基本類型,會出現編譯錯誤。可是若是將null賦值給包裝類object,而後將object賦給各自的基本類型,編譯器不會報,可是你將會在運行時期遇到空指針異常。這是Java中的自動拆箱致使的。

5) 任何含有null值的包裝類在Java拆箱生成基本數據類型時候都會拋出一個空指針異常。一些程序員犯這樣的錯誤,他們認爲自動裝箱會將null轉換成各自基本類型的默認值,例如對於int轉換成0,布爾類型轉換成false,可是那是不正確的,以下面所示:spa

Integer iAmNull =  null ;
int  i = iAmNull;  // Remember - No Compilation Error
 
可是當你運行上面的代碼片斷的時候,你會在控制檯上看到主線程拋出空指針異常。在使用HashMap和Integer鍵值的時候會發生不少這樣的錯誤。當你運行下面代碼的時候就會出現錯誤。
public class Test3 {
  public static void main(String args[]) throws InterruptedException {
    Map numberAndCount = new HashMap<>();
    int[] numbers = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
    for(int i : numbers){
      int count = (int) numberAndCount.get(i);//NullPointerException       numberAndCount.put(i, count++);     }   } }

package test; 
import java.util.HashMap;
import java.util.Map;

public class Test3 {
  public static void main(String args[]) throws InterruptedException {
    Map numberAndCount = new HashMap<>();
    Integer[] numbers = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};

    for(Integer i : numbers){
      Integer count = (Integer) numberAndCount.get(i);
      numberAndCount.put(i, count++); // NullPointerException
    }   
  }
}

這段代碼看起來很是簡單而且沒有錯誤。你所作的一切是找到一個數字在數組中出現了多少次,這是Java數組中典型的尋找重複的技術。開發者首先獲得之前的數值,而後再加一,最後把值放回Map裏。程序員可能會覺得,調用put方法時,第一種方式是轉換int報空指針,驗證以前說的。第二種方式,自動裝箱會本身處理好拆裝箱問題,可是忘記了當一個數字沒有計數值的時候,get方法返回null,而不是0,由於Integer的默認值是null而不是0。當把null值傳遞給一個int型變量的時候自動裝箱將會返回空指針異常。

 

引用了這麼多,如何避免空指針異常和null值賦予出現的編譯錯誤,重點來講就是理解null值的正確用法,在方法引用時多加幾層防禦措施,例如在給int類型set或get的時候進行如if( int i>=0)的斷定或者在沒有給int型賦值時給予默認值0或者在數據庫表中設置默認值0。

 

參考資料:

http://www.importnew.com/14229.html

https://blog.csdn.net/chenyuangege/article/details/50180313

相關文章
相關標籤/搜索