在一次定时任务获取时间的时候发现,使用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类型的处理器,包括LocalDateTimeTypeHandler、LocalDateTypeHandler、LocalTimeTypeHandler等,可以直接将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配置文件中手动配置类型处理器。