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

相关文章
相关标签/搜索