2017-01-18 22 views
2

私はKotlinを初めて使い、spring-data-mongodbを試してみます。下記の例を参照してください(メモリ内のMongoDbで完全実行可能なMavenプロジェクト:https://github.com/danielsindahl/spring-boot-kotlin-exampleとしても利用可能です)。Kotlinでspring-data-mongodbを使用した場合の例外

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}") 
    } 
} 
そのユーザ名がNULL可能であるので、私は、ユーザーデータのクラスを変更する場合

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

は、すべての作品:

テストKotlinIntegrationTest.persistenceTestを実行している、私はMongoDBのからユーザーオブジェクトを取得しようとすると、次のエラーメッセージが表示されます。

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

私は、このような場合は、なぜ私は、ユーザ名がNULL可能にしたくないので、理解したいと思います。 Kotlinで私のUserクラスを定義するための代替方法がありますか?

多くのおかげで、 ダニエル

答えて

3

はい、それは既知の問題です。 Userクラスのバイトコードがどのように見えるかをチェックする必要があります。 Javaは、すべてのパラメータが存在するコンストラクタを見て、2番目のパラメータに対してnull値で呼び出そうとします。あなたは何ができるか

は、あなたのコンストラクタに@JvmOverloadsを追加しようとすることです - これは、コンストラクタのすべてのバージョンを生成するために、Kotlinコンパイラを強制されますので、春データモンゴは、(@PersistenceConstructorを取り除く)、正しいものを選ぶことができます。

デフォルトなしの1コンストラクタを定義することもできます - Javaベースのフレームワークの場合のみ、2番目のコンストラクタの場合はデフォルトをいくつか使用します。または...

私はあなたの今のようなことを書くとき、私は通常のドメインオブジェクト(データベース上の一種の抽象)からマッピングされるデフォルト値のない単純な「永続性」データクラスを作成します。開始時にオーバーヘッドが発生する可能性がありますが、ドメインモデルをストレージモデルと緊密に結びつけないようにすることは、とにかく良いアイデアです。

+0

ありがとうRafal、大変感謝しています。私は完全に理解しているかわからない。なぜ、SpringはインストラクターをuserNameのnull値で呼び出すのですか?なぜ、データベースからロードしたuserNameを使用しないのですか? – Daniel

+0

申し訳ありません(とLOL)私はそこに間違っているかもしれません...第二引数に@Fieldを追加してみてください:) –

+0

これは受け入れられる回答でしょう! ( '@ JvmOverloads') –

関連する問題