org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Error instantiating class com.keysking.affairs.domains.user.entity.UserRole with invalid types (long,Role) or values (4,null). Cause: java.lang.reflect.InvocationTargetException

如果你在使用kotlin和mybatis,那你非常有可能碰见上面的问题,
这个问题出现的原因,是mybatis企图寻找一个无参构造函数,
但是data class并没有提供一个无参构造函数.

@TableName("user_role")
class UserRole(
    var user: Long,
    var role: Role
) : BaseEntity()

于是,你到网络上寻找答案,找到了一种解决方案:

@TableName("user_role")
class UserRole(
    var user: Long?=null,
    var role: Role?=null
) : BaseEntity()

这可把视编程为艺术的你恶心坏了,原本优雅的kotlin,因此充满了?和!!
你在想,有没有更好的解决办法...你苦苦寻找,却没有结果
直到....你看到了本文(滑稽)

优雅解决方案

其实,类似的这种情况,伟大的jetbrains早已帮我们想到了,于是他给我们提供了NoArg解决方案.

通过这种方案,在最终生成的字节码中,将会为data class生成一个无参构造方法,但是在kotlin的编写过程中,你却找不到这个构造方法的踪影. 优雅,高效!

接下来提供maven的解决办法(gradle的可以看这里)

首先,在你的工程中新建一个注解,叫做NoArg,例如这样:

package com.keysking.demo.common.anno

annotation class NoArg

然后修改你的pom.xml文件,在<build>标签中做如下修改(关注带注释部分):

<build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                        <!-- 这里!! kotlin官方插件,为被注解的指定类添加无参构造方法 -->
                        <plugin>no-arg</plugin>
                    </compilerPlugins>
                    <pluginOptions>
                        <!-- 这里!! 配置你刚刚新建的NoArg注解 -->
                        <option>no-arg:annotation=com.keysking.demo.common.anno.NoArg</option>
                        <!-- 在合成的构造函数中调用实例初始化器 -->
                        <!-- <option>no-arg:invokeInitializers=true</option> -->
                    </pluginOptions>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                    <!-- 这里!! 引入NoArg解决方案 -->
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-noarg</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

修改完以后重新刷一下maven,让pom.xml文件生效.

最后,在你可怜的data class上加上NoArg注解,便大功告成~

@NoArg
@TableName("user_role")
class UserRole(
    var user: Long,
    var role: Role
) : BaseEntity()

好了,在点赞之后,继续享受你优雅的kotlin吧~

Last modification:December 16th, 2020 at 04:35 pm
如果觉得我的文章对你有用,请随意赞赏