一、问题
新的项目试用一下kotlin, 调用数据库查询数据的时候报了这个问题:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: No constructor found in com.neusoft.collect.entity.cm.CmRoom matching [java.lang.String, java.lang.String, java.lang.String, java.lang.Integer, java.lang.String, java.lang.Double, java.lang.Double]
二、原因
因为使用的是kotlin data class,通过mybatis查询返回不是data class中全部的字段,kotlin创建对象本身是没有无参构造器的,Java默认包含无参构造器;data class 是要返回所有字段,而业务不需要返回所有字段,这是问题出现的所在。
三、处理办法
通过引用No-Arg 插件,官网地址:No-arg compiler plugin | Kotlin Documentation
四、工程样例
注意: <option>no-arg:annotation=com.neusoft.collect.config.NoArg</option> 和 创建的annotation class 路径保持一致
1、maven 部分引包
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<springfox.swagger3.version>3.0.0</springfox.swagger3.version>
<kotlin.version>2.0.0</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration>
<compilerPlugins> <!-- Or "jpa" for JPA support -->
<plugin>no-arg</plugin>
</compilerPlugins>
<pluginOptions>
<option>no-arg:annotation=com.neusoft.collect.config.NoArg</option>
<!-- Call instance initializers in the synthetic constructor -->
<!-- <option>no-arg:invokeInitializers=true</option> -->
</pluginOptions> </configuration>
</plugin>
</plugins>
</build>
2、创建 annotation class
package com.neusoft.collect.config
/**
* @author zc
* @date 2024/06/18 10:31
* @desc
*/
annotation class NoArg
3、data class 样例 引用 annotation class NoArg
package com.neusoft.collect.entity.cm
import com.neusoft.collect.config.NoArg
import java.io.Serializable
/**
* @author zc
* @date 2024/06/05 16:33
* @desc 机房
*/
@NoArg
data class CmRoom(
/**
* 多云统一名称
*/
var mc_uniform_name: String,
/**
* 详细地址
*/
var detailed_address: String,
/**
* 机楼名称
*/
var building_name: String,
/**
* 机房所在楼层
*/
var floor: Int,
/**
* 机房房间号
*/
var room_num: String,
/**
* 机房总行数
*/
var row_count: Int?,
/**
* 机房总列数
*/
var column_count: Int?,
/**
* 规划机架数
*/
var project_rack_count: Int?,
/**
* 占用机架数
*/
var occupation_rack_count: Int?,
/**
* 共用情况 枚举值:仅省级云使用、与其他业务共用
*/
val share_statistic: String = "仅省级云使用",
/**
* 机房数据维护责任人
*/
val data_maintain_vendor: String = "李剑春",
/**
* 关联资源池节点
*/
var rel_res_pool_id: String,
/**
* 所属数据中心
*/
val rel_dc_id: String = "JX001CPC-RP-JX-01",
/**
* 资源ID
*/
var resource_id: String
): Serializable
4、mapper 样例: 返回部分字段
/**
* Room
* 机房
* @return
*/
@Select(
"SELECT name AS mc_uniform_name," +
" address AS detailed_address," +
" building_name," +
" floor," +
" '001' AS room_num," +
" #{province} + '004' + pool_alias AS rel_res_pool_id," +
" #{province} + '002' + instance_id AS resource_id" +
" FROM cm_room_t"
)
fun room(province: String): List<CmRoom>