Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Not A Bug
-
Affects Version/s: 2.0-M2
-
Fix Version/s: None
-
Component/s: Persistence, Testing
-
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
- is duplicated by
-
GRAILS-8401
In a unit test save(validate: false) fails if an association is null
-
- is related to
-
GRAILS-8192
Provide a way to create partial domain class object graphs in unit tests
-
This is correct, because in real gorm you would get a similar hibernate error since the column will not be nullable