LoginSignup
3
3

More than 5 years have passed since last update.

Grails Script (gant) で session を flush する

Last updated at Posted at 2014-04-12

症状

Gant Scripts 中で任意のサービスメソッドを呼び出した際に、session が flushされない
(変更が保存されない)

grails-app/services/UserService.groovy
def updateUser() {
    User user = User.findById(1L)
    user.doSomething()
    user.save()
}
scripts/Test.groovy
// サービスメソッドをcall
def service = appCtx.getBean("userService")
service.updateUser()

解 1: 'flush: true'

UserService.groovy を書き換えるという、元も子もない対策。
これで済むなら問題ない。

grails-app/services/UserService.groovy
def updateUser() {
    User user = User.findById(1L)
    user.doSomething()
    user.save(flush: true)
}

解 2: Transactionalアノテーションを利用する

  1. サービスに static transactional = false を設定し、NonTransactional な Bean にする。
  2. メソッドを抜けるときにflushするよう、Transactional アノテーションを付加する
grails-app/services/UserService.groovy
@Transactional
def updateUser() {
    User user = User.findById(1L)
    user.doSomething()
    user.save()
}

補足

static transactional = false を設定しないまま、

grails-app/services/UserService.groovy
@Transactional(propagation=Propagation.REQUIRES_NEW)
def updateUser() {
    User user = User.findById(1L)
    user.doSomething()
    user.save()
}

も実験したが、動作せず

解 3: 明示的flush (recommended)

Grails に同梱されている scripts/RunScript.groovy を参考に、スクリプトを以下のように修正する

Test.groovy
def persistenceInterceptor = appCtx.containsBean('persistenceInterceptor') ? appCtx.persistenceInterceptor : null
persistenceInterceptor?.init()
try {

    // サービスメソッドをcall
    def service = appCtx.getBean("userService")
    service.updateUser()

}
finally {
    persistenceInterceptor?.flush()
    persistenceInterceptor?.destroy()
}

解1,2と比べると一見冗長で汚く見えるが、コードがいくらスッキリしたところでサービス側に手を加える事自体が本来的でない。更に言えば Spring のアノテーションは記述量こそ少ないが、挙動は別途調べ、覚えておく必要がある。他のプログラマが見た時の学習コストも鑑みると、こういった Grails 的なコードの方が見通しが良く合理的だと思う。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3