我是Kotlin的新手,并尝试使用spring-data-mongodb。请参阅下面的示例(此处也可用作内存中MongoDb的完全可运行的Maven项目: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检索User对象时收到以下错误消息:
org.springframework.data.mapping.model.MappingException: No property null found on entity class dsitest.User to bind constructor parameter to!
如果我修改User数据类以便userName可以为空,那么一切正常。
data class User @PersistenceConstructor constructor(@Id val id: String? = null,
val userName: String? = null)
我想了解为什么会这样,因为我不希望userName可以为空。在Kotlin中有一些替代的,更好的方法来定义我的User类吗?
非常感谢, 丹尼尔
答案 0 :(得分:3)
是的,这是一个已知问题。您应该检查User类的字节码是什么样的。 Java看到包含所有参数的构造函数,并尝试使用第二个的null值调用它。
你可以做的是尝试将@JvmOverloads
添加到构造函数中 - 这将迫使Kotlin编译器生成构造函数的所有版本,因此Spring Data Mongo可以选择正确的版本(摆脱@PersistenceConstructor) )然后。
您还可以定义1个没有默认值的构造函数 - 仅适用于基于Java的框架,第二个版本默认为您。还是......
当我像现在这样写东西时,我创建了简单的'持久性'数据类,没有任何默认值,无论是映射到我的常规域对象还是从我的常规域对象(对数据库的一种抽象)。它可能会在开始时产生一些开销 - 但保持您的域模型与存储模型的紧密耦合通常是一个好主意。