Dónal
Dónal

Reputation: 187499

Grails cascade delete

In my Grails domain I have a 1:1 relationship between Artist and MusicianDetails

class Artist {

    static hasOne = [musicianDetails: MusicianDetails]

    static constraints = {
        musicianDetails(nullable: true, unique: true)
    }           
}

class MusicianDetails {
    static belongsTo = [artist: Artist]
}

I want deletes of Artist to cascade to the associated MusicianDetails. However, I get a foreign key contraint violation when I delete an Artist with:

Artist.executeUpdate("delete Artist a where a.id = ?", [artistId])

The error message is:

Class
    com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException
Message
    Cannot delete or update a parent row: a foreign key constraint fails 
    (`festival2`.`musician_details`, CONSTRAINT `FKA0E6B2145ACE528E` 
    FOREIGN KEY (`artist_id`) REFERENCES `artist` (`id`))

What is the correct way to defined a 1:1 relationship between Artist and MusicianDetails such that deletes of the former cascade to the latter?

Upvotes: 4

Views: 2341

Answers (2)

Dónal
Dónal

Reputation: 187499

The cascading works if I delete the artist using

artist.get(artistId)?.delete()

instead of

Artist.executeUpdate("delete Artist a where a.id = ?", [artistId])

Upvotes: 1

Krzysztof Cygan
Krzysztof Cygan

Reputation: 310

You need a belongsTo in MusicianDetails. Not sure but you might also need to cascade all-delete-orphan.

Anyways it seems as if Musician Details can be an embedded class of Artist, so that it is mapped to one database table.

http://bartling.blogspot.com/2009/04/embedded-domain-components-in-grails.html?m=1

Another thing is, that it is better to do Artist.get(artistId).delete() instead of executing a HQL query. This makes code less prone to errors, more understandable and you can always change GORM to another implementation if you want to get rid of Hibernate for any reason.

Upvotes: 0

Related Questions