MyBatis解析LocalDateTime发生嵌套异常错误

992 阅读3分钟

在一次定时任务获取时间的时候发现,使用LocalDateTime去获取现在的时间会发生嵌套异常错误

 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logAspect': Unsatisfied dependency expressed through field 'logService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logServiceImpl': Unsatisfied dependency expressed through field 'logMapper'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'logDao' defined in file [D:\ideacode\taneilife\target\classes\com\xmkj\tanelife\project\common\dao\LogDao.class]: Unsatisfied dependency expressed through bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.springframework.core.NestedIOException: Failed to parse mapping resource: 'file [D:\ideacode\taneilife\target\classes\mybatis\manage\hotwatersystem\StatisticsTaskMapper.xml]'; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'statisticsTime'. It was either not specified and/or could not be found for the javaType (java.time.LocalDateTime) : jdbcType (null) combination.

这个异常的原因是Spring容器中的某个bean依赖的另一个bean无法满足依赖关系,导致创建bean失败。

根据异常信息,可以看到有多个嵌套的UnsatisfiedDependencyException异常。其中,最内层的异常提示java.time.LocalDateTime类型无法找到对应的类型处理器(Type handler),这可能是因为Mybatis没有正确配置java.time.LocalDateTime类型的类型处理器。

解决方法一:

在Mybatis的配置文件中为java.time.LocalDateTime类型配置对应的类型处理器。可以在mybatis-config.xml中添加以下配置:

 <typeHandlers>
   <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" />
 </typeHandlers>

这里使用了Mybatis内置的LocalDateTimeTypeHandler类型处理器来处理java.time.LocalDateTime类型。

.yml文件中可以添加以下配置:

 mybatis:
   type-handlers-package: com.example.mybatis.typehandler

上面的配置指定了Mybatis类型处理器所在的包路径,Mybatis会自动扫描该包下的所有类型处理器,并注册到类型处理器Registry中。

如果你只需要为某个特定的Java类型配置类型处理器,可以使用以下方式:

 mybatis:
   configuration:
     typeHandlers:
       - type: com.example.UserType
         handler: com.example.UserTypeHandler

上面的配置指定了为Java类型com.example.UserType配置类型处理器com.example.UserTypeHandler

如果需要配置java.time.LocalDateTime类型的类型处理器,可以使用以下方式:

 mybatis:
   configuration:
     typeHandlers:
       - type: java.time.LocalDateTime
         handler: org.apache.ibatis.type.LocalDateTimeTypeHandler

上面的配置指定了为Java类型java.time.LocalDateTime配置类型处理器org.apache.ibatis.type.LocalDateTimeTypeHandler

需要注意的是,如果你的项目使用了Spring Boot和Mybatis的集成,那么上面的配置可以直接放在application.yml文件中。

如果你使用的是Mybatis 3.5及以上版本,可以直接使用org.apache.ibatis.type.LocalDateTimeTypeHandler来处理java.time.LocalDateTime类型,无需额外配置。

另外,需要注意的是,在使用Mybatis操作MySQL数据库时,MySQL 5.6.4及以上版本已经支持直接存储LocalDateTime类型,因此可以将java.time.LocalDateTime类型直接映射到MySQL的DATETIME类型。如果你在数据库中使用的是其他类型,需要根据情况选择合适的类型处理器。

解决方法二(推荐):

添加下面的这个依赖:

 <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-typehandlers-jsr310 -->
 <dependency>
     <groupId>org.mybatis</groupId>
     <artifactId>mybatis-typehandlers-jsr310</artifactId>
     <version>1.0.2</version>
 </dependency>

该依赖提供了一组JSR-310类型的处理器,包括LocalDateTimeTypeHandlerLocalDateTypeHandlerLocalTimeTypeHandler等,可以直接将java.time包下的数据类型映射到数据库字段。在使用时,只需要在Mybatis的配置文件中指定该处理器即可,无需自己手动配置类型处理器。

添加依赖后,可以在Mybatis配置文件(如mybatis-config.xml)中指定该类型处理器,例如:

 <typeHandlers>
     <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler" javaType="java.time.LocalDateTime"/>
 </typeHandlers>

注意,如果使用了Mybatis Spring Boot Starter依赖,只需要添加mybatis-typehandlers-jsr310依赖即可,无需在Mybatis配置文件中手动配置类型处理器。