アレについて記す

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 = {</pre>
    <pre class="green">
        flashCards cascade: 'all-delete-orphan' // この設定が必要!</pre>
    <pre class="bottom">
    }
}

[ 子クラス ]

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()
}


以上です。