Grails
  1. Grails
  2. GRAILS-8190

DataIntegrityViolationException with in-memory GORM and save(validate: false)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Not A Bug
    • Affects Version/s: 2.0-M2
    • Fix Version/s: None
    • Component/s: Persistence, Testing
    • Labels:
    • Environment:
      Kubuntu linux 11.10, Intellij IDEA 10
    • Testcase included:
      yes

      Description

      I have domain classes and unit test and test like this:

      class Blog {
          String name
      }
      class Post {
          Blog blog
          String text
          static constraints = { blog(nullable: false) }
      }
      
      @TestFor(Post)
      class PostTests {
          void testPostSave() {
              assert null == new Post().save()
              assert null != new Post().save(validate: false) // DataIntegrityViolationException unless constraint changed to blog(nullable: true)
              assert 1 == Post.count()
          }
      }
      

      Peter Ledbrook in this article: http://blog.springsource.com/2011/06/07/countdown-to-grails-1-4-unit-testing/ says clearly:

      One question you may ask is why does the above example use the validate: false option when saving the new domain instance? You have to remember that you are working against a full GORM implementation and so validation takes effect by default. For a simple domain class this isn't a problem, but what if you have tens of properties and some required relationships too? Building a valid graph of domain instances can involve considerable effort and yet the method or action under test may only access one or two properties of the domain class. Disabling validation removes what would otherwise be an onerous requirement.
      For example, imagine that the Post domain class had a required user property of type User. Now, the list action doesn't care about the user at all - it's just returning a list of posts. But with validation enabled, you would have to create a dummy User instance and attach it to the Post instance. Scale that up to a complex domain model and you can see that validation is not your friend in this particular case.

      In this case Post has required Blog property, but in-memory GORM implementation throws:

      org.springframework.dao.DataIntegrityViolationException: Cannot save object [validationerror.Post : 1] of type [validationerror.Post]. The association [validationerror.Post->blog] is cannot be null.
      	at org.grails.datastore.mapping.engine.NativeEntryEntityPersister.persistEntity(NativeEntryEntityPersister.java:784)
      	at org.grails.datastore.mapping.engine.EntityPersister.persist(EntityPersister.java:130)
      	at org.grails.datastore.mapping.core.AbstractSession.persist(AbstractSession.java:462)
      	at org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:166)
      	at org.grails.datastore.gorm.GormInstanceApi$_save_closure4.doCall(GormInstanceApi.groovy:143)
      	at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:301)
      	at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:34)
      	at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:142)
      	at validationerror.PostTests.testPostSave(PostTests.groovy:16)
      

      I attach sample application with Unit tests.

        Issue Links

          Activity

          Hide
          Graeme Rocher added a comment -

          This is correct, because in real gorm you would get a similar hibernate error since the column will not be nullable

          Show
          Graeme Rocher added a comment - This is correct, because in real gorm you would get a similar hibernate error since the column will not be nullable
          Hide
          Tomasz Kalkosinski added a comment -

          So is Peter wrong in his article then and it should be corrected?

          Show
          Tomasz Kalkosinski added a comment - So is Peter wrong in his article then and it should be corrected?
          Hide
          Peter Ledbrook added a comment -

          Just to clarify: it was correct at the time of writing. Grails behaviour has changed since then.

          Show
          Peter Ledbrook added a comment - Just to clarify: it was correct at the time of writing. Grails behaviour has changed since then.
          Hide
          Tomasz Kalkosinski added a comment -

          Thank you for your clarification Peter.

          Show
          Tomasz Kalkosinski added a comment - Thank you for your clarification Peter.

            People

            • Assignee:
              Unassigned
              Reporter:
              Tomasz Kalkosinski
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development