Grails remove orphans many-to-many relationship
-
01-07-2021 - |
Frage
A simple blog application, Grails 1.3.9 and MySQL, a many-to-many relationship between two domain-classes, BlogPost And Tag
class BlogPost {
String title
String teaser
String body
Date updated
Category category
Integer priority
static hasMany = [comments:Comment,tags:Tag]
static belongsTo = [Category,Tag]
static searchable = true
String toString() {
"$title"
}
static constraints = {
title(nullable:false,blank:false,lenght:1..50)
teaser(nullable:false,blank:false,lenght:1..100)
body(nullable:false,blank:false,maxSize:5000)
updated(nullable:false)
category(nullable:false)
priority(nullable:false)
}
}
class Tag {
String name
String description
static hasMany = [blogpost:BlogPost]
static searchable = true
String toString() {
"$name"
}
static constraints = {
name(nullable:false,blank:false)
description(nullable:false,blank:false)
}
}
Hibernate creates in MySQL three related tables: blog_post, tag and tag_blogpost
Now if I create a tag X related to a blogpost Y, and then delete Y, an orphaned row remain in tag_blogpost table, and the show view for tag X throws and exception "No row with the given identifier exists:[...]"
How can I automatically remove (on cascade) orphaned row in tag_blogpost table?
Lösung
In your model, is correct to have two relationships between BlogPost and Tag? To create a BlogPost you must have one tag and also can be n tags?
The tag that you created was associated to BlogPost as the tag attribute or in the tags list?
If it's in the tags list, I think that Grails consider your model as a many-to-many and according to the docs:
Many-to-many: only saves cascade from the "owner" to the "dependant", not deletes.
Thinking in the post-tags model I think that your approach could be a many-to-many relationship and manually handle the delete of a tag, deleting the posts before. If you really need to have at least one tag with the post, in the view of the BlogPost you can force the user to select a tag.
Andere Tipps
Actually this modified model works for me
class BlogPost {
String title
String teaser
String body
Date updated
Integer priority
static hasMany = [blogPostTags:BlogPostTag]
static belongsTo = [Category]
String toString() {
"$title"
}
static constraints = {
title(nullable:false,blank:false,lenght:1..50)
teaser(nullable:false,blank:false,lenght:1..100)
body(nullable:false,blank:false,maxSize:5000)
updated(nullable:false)
priority(nullable:false)
}
}
class Tag {
String name
String description
static hasMany = [blogPostTags:BlogPostTag]
String toString() {
"$name"
}
static constraints = {
name(nullable:false,blank:false)
description(nullable:false,blank:false)
}
}
class BlogPostTag {
BlogPost blogPost
Tag tag
static belongsTo = [BlogPost,Tag]
static constraints = {
blogPost(nullable:false)
tag(nullable:false)
}
}