root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "XXX")


  1. org.apache.catalina.core.StandardWrapperValve invoke  
  2. threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException:   
  3. nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'video.issuer!=null'.   
  4. Cause: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null"issuer")] with root cause  
  5. org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null"issuer")  

最近在Mybatils的使用中,为了方便使用resultMap完成关联查询并实现javaBean对象到mapper.xml的高效传值,使用嵌套对象属性如下:

[java]  view plain  copy
  1. public class Report{  
  2.          private  String reportId;  
  3.          private String  videoId;  
  4.          private Video  video;  
  5. }  

[java]  view plain  copy
  1. public class Video{  
  2.          private  String videoId;  
  3.          private String  videoName;  
  4.          private Customer  issuer;  
  5. }  

[java]  view plain  copy
  1. public class Customer{  
  2.          private  String customerId;  
  3.          private String  nickName;  
  4. }  

在执行项目的时候,出现如上错误:问题一出现,第一反应是就怀疑Mybatils强大的映射机制!查看官方文档得到如下内容


翻译:

parameterType 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。
resultType 从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。
尽管文档上说:parameterType 因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。但是问题出现之后,我立马将mapper.xml改写

改写前:

root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null,

改写后:

root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null,

发现改写之后,仍然没有任何作用,最后通过仔细阅读异常日志,发现,异常实际是在Mybatils执行映射处理的时候发生的,属性“XXX”找不到调用自己的所有者对象(NULL),所以抛出异常

[java]  view plain  copy
  1. org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null"issuer")  

那为什么我在配置ResultMap时没有出现该异常呢?因为原因是Mybatils的"映射方向"——“拿”和“放”不相同。resultMap配置如下:

[html]  view plain  copy
  1. <resultMap type="com.local.entity.Report" id="findMap" autoMapping="true">  
  2.     <id property="reportId" column="reportId"/>  
  3.     <association property="reporting" javaType="com.local.entity.Customer">  
  4.       <id property="customerId" column="customerId"/>  
  5.       <result property="nickName" column="nickName"/>  
  6.       <result property="phone" column="phone"/>  
  7.     association>  
  8.     <association property="video" javaType="com.local.entity.Video">  
  9.       <id property="videoId" column="videoId"/>  
  10.       <association property="issuer" javaType="com.local.entity.Customer">  
  11.        <id property="customerId" column="vcId"/>  
  12.        <result property="nickName" column="vcName"/>  
  13.        <result property="phone" column="vcPhone"/>  
  14.      association>  
  15.     association>  
  16.   resultMap>  

其根本原因还是我们常见的:java.lang.NullPointerException

只不过该异常被Mybatils封装了,就像Spring把常见的SqlException封装成org.springframework.dao.XXXException一样,解决方法如下:  


第一种,对象属性要用new 进行初始化:

public class Report{  
         private  String reportId;  
         private String  videoId;  
         private Video  video=new Video();  
}  
public class Video{  
         private  String videoId;  
         private String  videoName;  
         private Customer  issuer=new Customer();  
}

第二种,一步步判断字段(属性)所有者是否为空:

root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null,

你可能感兴趣的:(Mybatils,Exception)