-
- org.apache.catalina.core.StandardWrapperValve invoke
- threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException:
- nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'video.issuer!=null'.
- Cause: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "issuer")] with root cause
- org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "issuer")
最近在Mybatils的使用中,为了方便使用resultMap完成关联查询并实现javaBean对象到mapper.xml的高效传值,使用嵌套对象属性如下:
- public class Report{
- private String reportId;
- private String videoId;
- private Video video;
- }
- public class Video{
- private String videoId;
- private String videoName;
- private Customer issuer;
- }
- public class Customer{
- private String customerId;
- private String nickName;
- }
在执行项目的时候,出现如上错误:问题一出现,第一反应是就怀疑Mybatils强大的映射机制!查看官方文档得到如下内容
翻译:
parameterType | 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。 |
resultType | 从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。 |
尽管文档上说:parameterType
因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。但是问题出现之后,我立马将mapper.xml改写
改写前:
改写后:
发现改写之后,仍然没有任何作用,最后通过仔细阅读异常日志,发现,异常实际是在Mybatils执行映射处理的时候发生的,属性“XXX”找不到调用自己的所有者对象(NULL),所以抛出异常
- org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "issuer")
那为什么我在配置ResultMap时没有出现该异常呢?因为原因是Mybatils的"映射方向"——“拿”和“放”不相同。resultMap配置如下:
- <resultMap type="com.local.entity.Report" id="findMap" autoMapping="true">
- <id property="reportId" column="reportId"/>
- <association property="reporting" javaType="com.local.entity.Customer">
- <id property="customerId" column="customerId"/>
- <result property="nickName" column="nickName"/>
- <result property="phone" column="phone"/>
- </association>
- <association property="video" javaType="com.local.entity.Video">
- <id property="videoId" column="videoId"/>
- <association property="issuer" javaType="com.local.entity.Customer">
- <id property="customerId" column="vcId"/>
- <result property="nickName" column="vcName"/>
- <result property="phone" column="vcPhone"/>
- </association>
- </association>
- </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();
}
第二种,一步步判断字段(属性)所有者是否为空: