1前書き

Kotlinの特徴の1つはリンクです:/kotlin-java-interoperability[Javaとの相互運用性]ライブラリ、そしてJPAは確かにこれらのうちの1つです。

このチュートリアルでは、JPAエンティティとして

Kotlinデータクラス

の使い方を探ります。


2依存関係

簡単にするために、JPAの実装としてHibernateを使用します。 Mavenプロジェクトに次の依存関係を追加する必要があります。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.15.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-testing</artifactId>
    <version>5.2.15.Final</version>
    <scope>test</scope>
</dependency>

テストを実行するためにH2埋め込みデータベースも使用します。

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
    <scope>test</scope>
</dependency>

Kotlinでは、以下を使用します。

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jdk8</artifactId>
    <version>1.2.30</version>
</dependency>

もちろん、最新バージョンのhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22org.hibernate%22%20AND%20a%3A%22hibernate-core%22[Hibernate]、https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.h2database%22%20AND%20a%3A%22h2%22[H2]、https://search .maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.jetbrains.kotlin%22%20AND 20a%3A%22kotlin-stdlib-jdk8%22[Kotlin]はMaven Centralにあります。


3コンパイラプラグイン(jpa-plugin)

JPAを使用するには、エンティティクラスにパラメータなしのコンストラクタが必要です。

デフォルトで、Kotlinデータクラスはそれを持っていません、そしてそれらを生成するために我々はhttps://kotlinlang.org/docs/reference/compiler-plugins.html#jpa-support[jpa-plugin]を使う必要があるでしょう:

<plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>1.2.30</version>
    <configuration>
        <compilerPlugins>
        <plugin>jpa</plugin>
        </compilerPlugins>
        <jvmTarget>1.8</jvmTarget>
    </configuration>
    <dependencies>
        <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-maven-noarg</artifactId>
        <version>1.2.30</version>
        </dependency>
    </dependencies>
    <!--...-->
</plugin>


4 Kotlinデータクラスを使ったJPA

前の設定が完了したら、JPAをデータクラスと共に使用する準備が整いました。

このように、

id



name

の2つの属性を持つ

Person

データクラスの作成を始めましょう。

@Entity
data class Person(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int,

    @Column(nullable = false)
    val name: String
)

ご覧のとおり、

@ Entity、@Column



@ Id

など、JPAのアノテーションを自由に使用できます。

私たちの実体が動いているのを見るために、次のテストを作成します

@Test
fun givenPerson__whenSaved__thenFound() {
    doInHibernate(({ this.sessionFactory() }), { session ->
        val personToSave = Person(0, "John")
        session.persist(personToSave)
        val personFound = session.find(Person::class.java, personToSave.id)
        session.refresh(personFound)

        assertTrue(personToSave == personFound)
    })
}

ロギングを有効にしてテストを実行すると、次のような結果が得られます。

Hibernate: insert into Person (id, name) values (null, ?)
Hibernate: select person0__.id as id1__0__0__, person0__.name as name2__0__0__ from Person person0__ where person0__.id=?

それはすべてが順調に進んでいることの指標です。 +実行時に

jpa-plugin

を使用しない場合、デフォルトのコンストラクタがないため、__InstantiationExceptionが発生します。

javax.persistence.PersistenceException: org.hibernate.InstantiationException: No default constructor for entity: : com.baeldung.entity.Person

それでは、もう一度

null

値でテストします。これを行うには、新しい属性

email



@ OneToMany

関係を使用して

Person

エンティティを拡張しましょう。

   //...
    @Column(nullable = true)
    val email: String? = null,

    @Column(nullable = true)
    @OneToMany(cascade =[CascadeType.ALL])
    val phoneNumbers: List<PhoneNumber>? = null


email

フィールドと

phoneNumbers

フィールドはNULL可能であるため、疑問符で宣言されていることもわかります。


PhoneNumber

エンティティには、

id



number

の2つの属性があります。

@Entity
data class PhoneNumber(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int,

    @Column(nullable = false)
    val number: String
)

テストでこれを確認しましょう。

@Test
fun givenPersonWithNullFields__whenSaved__thenFound() {
    doInHibernate(({ this.sessionFactory() }), { session ->
        val personToSave = Person(0, "John", null, null)
        session.persist(personToSave)
        val personFound = session.find(Person::class.java, personToSave.id)
        session.refresh(personFound)

        assertTrue(personToSave == personFound)
    })
}

今回は、1つのinsert文を受け取ります。

Hibernate: insert into Person (id, email, name) values (null, ?, ?)
Hibernate: select person0__.id as id1__0__1__, person0__.email as email2__0__1__, person0__.name as name3__0__1__, phonenumbe1__.Person__id as Person__i1__1__3__, phonenumbe2__.id as phoneNum2__1__3__, phonenumbe2__.id as id1__2__0__, phonenumbe2__.number as number2__2__0__ from Person person0__ left outer join Person__PhoneNumber phonenumbe1__ on person0__.id=phonenumbe1__.Person__id left outer join PhoneNumber phonenumbe2__ on phonenumbe1__.phoneNumbers__id=phonenumbe2__.id where person0__.id=?

出力を検証するために

null

データなしでもう一度テストしましょう。

@Test
fun givenPersonWithFullData__whenSaved__thenFound() {
    doInHibernate(({ this.sessionFactory() }), { session ->
        val personToSave = Person(
          0,
          "John",
          "[email protected]",
          Arrays.asList(PhoneNumber(0, "202-555-0171"), PhoneNumber(0, "202-555-0102")))
        session.persist(personToSave)
        val personFound = session.find(Person::class.java, personToSave.id)
        session.refresh(personFound)

        assertTrue(personToSave == personFound)
    })
}

そして、ご覧のとおり、今度は3つのinsertステートメントが得られます。

Hibernate: insert into Person (id, email, name) values (null, ?, ?)
Hibernate: insert into PhoneNumber (id, number) values (null, ?)
Hibernate: insert into PhoneNumber (id, number) values (null, ?)


5結論

この簡単な記事では、jpa-pluginとHibernateを使ってKotlinデータクラスをJPAと統合する方法の例を見ました。

いつものように、ソースコードは利用可能です

https://github.com/eugenp/tutorials/tree/master/spring-mvc-kotlin

[over
GitHubで。