アレについて記す

GORM 1対多のcollection削除

Posted on April 28, 2014 at 12:30 (JST)

GrailsのGORMにてhasManyとbelongsToで1対多の関連を定義している場合、多の要素を全削除するために親クラスに下記の設定を行います。

親クラス
class Deck {
    String title  
static hasMany = [flashCards: Flashcard]
static mapping = {
        flashCards cascade: 'all-delete-orphan' // この設定が必要!
    }
}
  

子クラス
class Flashcard {  
String question String answer
static belongsTo = [deck: Deck] }

削除実行は下記のとおり

deck.flashCards.clear()
deck.save()

ちなみに試行錯誤時に発生した例外と、その時のソースも参考までに載せておきます。

deleted object would be re-saved by cascade (remove deleted object from associations): [com.dictarea.card.Flashcard#10]. Stacktrace follows:
org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.dictarea.card.Flashcard#10]
    at com.dictarea.card.DeckController.update(DeckController.groovy:74)
    at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
    at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
    at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.java:53)
    at grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter.doFilter(RequestHolderAuthenticationFilter.java:49)
    at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.java:82)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
deck.flashCards.each { card ->
    card.delete()
}

以上です。