Kotlin+SpringBootでWebアプリを作ってみる その2.1
発端
Kotlin+SpringBootでWebアプリを作ってみる その2でテストコードでLazyInitializationException
が出てはまったって話を書きました。
すると、槇さんがSpringの永続コンテキストのライフサイクルを教えてくださりました。
ありがたい... ということで書いておこうと思います。
Springにおける永続コンテキストの話
以下槇さんからいただいたツイート
@KissyBnts 通常Webだと境界はサービスになるので、viewからアクセスするといちいちエラーになるのが面倒で、Springだとインターセプタで永続コンテキストの境界をリクエストに広げています(Bootでは自動設定されます)。なので、Webでは動いてテストでこけていました
— Toshiaki Maki (@making) April 3, 2016
なるほど…。Spring Bootの庇護下になかったからなのか…。
つまりBookService.findAllBook()
の呼び出し終了時にEntityManager
をSpringが閉じてしまってるから、遅延初期化でエラーを吐いていたのですね。
で、@Transactional
をメソッドにアノテートすることでEntityManager
が閉じるのをメソッド単位にすると。するとメソッド内で遅延アクセスをしても問題無し。
ちなみに@Transactional
をクラスもしくはメソッドに付与するとfinal
やめろエラーが吐かれるのでopen
をつけましょう。
BookServiceTest.kt
package book.application.service import book.application.BookApplication import org.junit.Assert.* import org.junit.Test import org.junit.runner.RunWith import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationConfiguration import org.springframework.test.context.junit4.SpringJUnit4ClassRunner import org.springframework.test.context.web.WebAppConfiguration import javax.transaction.Transactional import org.hamcrest.CoreMatchers.`is` as be @RunWith(SpringJUnit4ClassRunner::class) @SpringApplicationConfiguration(BookApplication::class) @WebAppConfiguration open class BookServiceTest{ @Autowired lateinit var bookService: BookService @Test @Transactional fun findAllBookTest() { var sutList = bookService.findAllBook() var sut = sutList[0] assertThat(sutList.size, be(1)) assertThat(sut.id, be(1L)) assertThat(sut.title, be("title")) assertThat(sut.subTitle, be("subTitle")) assertThat(sut.leadingSentence, be("leading")) assertThat(sut.imagePath, be("imagePath")) assertThat(sut.url, be("url")) assertThat(sut.authors[0].name, be("author")) assertThat(sut.likeCount, be(0)) assertThat(sut.categories[0].name, be("category")) assertThat(sut.publisher.name, be("publisher")) } }
@Transactional
をクラスにアノテートしても、メソッドにアノテートしても動作します(入れ知恵)。
@KissyBnts テストメソッドかクラスに@ Transactinal付けてみてください
— Toshiaki Maki (@making) April 3, 2016
読もう
@KissyBnts 一連のツイートを読んだ後、https://t.co/IVfabSgKQO
— Toshiaki Maki (@making) April 3, 2016
を読めばなんとなく理解できるかと思います
所感
Spring Bootがやってくれてるから問題ないけど、わかってないことたくさんあるんだろうなぁって感じですね。
これからもちょくちょくはまりそうだな…。
にしても、わからないなーと思ってた部分を拾っていただけて教えていただけるなんて、ほんとにありがたいことです。
もっとインプット・アウトプットして少しでも恩を返せるようになれろうと思いながら書いていました。
槇さん、ありがとうございました!
そして僕は明日の仕事終わりにはじめてのSpring Bootを買いに行こうと決めました…。
GitHubにRepository作った
ここです。以上。