software development for the
existentially challenged
Older | Newer Older | Newer
one:many: Add the Child, Save the Parent
comment share
I always forget this and always go nuts for a while. It's obvious and basic but I forget, so sue me.

Creating a one:many relationship using an ordered List, instead of the default Se, when you are ready to save the new child, you have to remember to
  1. Create the child
  2. Add the child to the parent
  3. Save the PARENT
You cannot first create and save the child first then add it to the parent.
Say this is your ChildController's save() method:

RIGHT:
    // Do THIS
    def save = {
        def childInstance = new Child(params)
        Parent parent = childInstance.parent
        parent.addToChildren(childInstance)
        if (parent.save(flush: true) ...
WRONG:
    // Don't THIS in the name of all that is holy
    def save = {
        def childInstance = new Child(params)
        child.save(flush: true)
        parent.addToChildren(child)
        ...
If you do it the wrong way, Grails will explode with
org.hibernate.PropertyValueException: not-null property references 
a null or transient value: Child._Parent_childrenBackref
Remember: create the child, add it to the parent, and then save the parent.

This is mentioned in the Grails Reference Documentation under 5.2.4 Sets, Lists and Maps but as an "oh by the way" and doesn't actually give you the error above (though you can also get this error as well):
When using a List, elements must be added to the collection before being saved, otherwise Hibernate will throw an exception (org.hibernate.HibernateException: null index column for collection):

0 comments:

Post a Comment

What is this site?!

t (a professional software developer for a big company) writes about software development and stuff. Unix, Java, Groovy, OS X, and lots of open source libraries and tools.