在使用Kotlin时使用spring-data-mongodb的例外

我是Kotlin的新手,并试用spring-data-mongodb。 请看下面的例子(在这里也可以作为完全可运行的Maven项目与内存中的MongoDb: https : //github.com/danielsindahl/spring-boot-kotlin-example )。

Application.kt

package dsitest import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication open class Application fun main(args: Array<String>) { SpringApplication.run(Application::class.java, *args) } 

User.kt

 package dsitest import org.springframework.data.annotation.Id import org.springframework.data.annotation.PersistenceConstructor import org.springframework.data.mongodb.core.mapping.Document @Document(collection = "user") data class User @PersistenceConstructor constructor(@Id val id: String? = null, val userName: String) 

UserRepository.kt

 package dsitest import org.springframework.data.repository.CrudRepository interface UserRepository : CrudRepository<User, String> 

KotlinIntegrationTest.kt

 package dsitest import org.junit.Test import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.junit4.SpringRunner @RunWith(SpringRunner::class) @SpringBootTest class KotlinIntegrationTest constructor () { @Autowired lateinit var userRepository : UserRepository; @Test fun persistenceTest() { val user : User = User(userName = "Mary") val savedUser = userRepository.save(user) val loadedUser = userRepository.findOne(savedUser.id) // Failing code println("loadedUser = ${loadedUser}") } } 

当运行测试KotlinIntegrationTest.persistenceTest时,当试图从MongoDb中检索一个用户对象时,我得到以下错误信息:

 org.springframework.data.mapping.model.MappingException: No property null found on entity class dsitest.User to bind constructor parameter to! 

如果我修改用户数据类,以便userName为空,则一切正常。

 data class User @PersistenceConstructor constructor(@Id val id: String? = null, val userName: String? = null) 

我想明白为什么这样,因为我不希望userName为空。 有没有其他更好的方式来定义我的用户类在Kotlin?

非常感谢Daniel

是的,这是一个已知的问题。 你应该检查你的User类的字节码是怎样的。 Java看到了所有参数的构造函数,并尝试用第二个参数的空值来调用它。

你可以做的是尝试添加@JvmOverloads到你的构造函数 – 这将迫使Kotlin编译器生成构造函数的所有版本,所以Spring Data Mongo可以选择正确的(抛弃@PersistenceConstructor)。

你也可以定义1个没有默认值的构造函数 – 只适用于基于Java的框架,第二个构造函数的默认值是你自己的。 要么…

当我像现在这样写东西的时候,我创建了简单的“持久性”数据类,没有任何映射到/从我的常规域对象(一种数据库抽象)的默认值。 它可能会在开始时产生一些开销,但是保持域模型不与存储模型紧密结合通常是一个好主意。