문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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)
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top