Grails

saving an invalid modified instance in a transactional service fails

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Blocker Blocker
  • Resolution: Fixed
  • Affects Version/s: 1.0.4, 1.1
  • Fix Version/s: 1.1.1
  • Component/s: Persistence
  • Labels:
    None

Description

If you retrieve a persistent domain instance and set one or more invalid properties in a controller and attempt to save the instance in a transactional service method, validation isn't performed and the instance is flushed. If one of the validation problems involves a database constraint (e.g. nullable) then the call fails due to a database constraint violation.

I've attached a sample project to illustrate. Create a Thing instance and then edit it. Set the name to NULL, which forces the value to null since empty form fields are blank, not null. Rather than validating the instance and logging the messages, you'll get an error page with the error

org.springframework.dao.DataIntegrityViolationException:
not-null property references a null or transient value: Thing.name

I spent some time debugging this a while back and it looks like the call to the services getMetaClass() ends the transaction and triggers a flush, so the call to thingService.saveThing() never actually executes - you can see that from the console log messages.

I saw this in a 1.0.4 app and it's a problem in 1.1, but I haven't tested in 1.0.5.

Activity

Hide
Burt Beckwith added a comment -
Show
Burt Beckwith added a comment - See this discussion on the mailing list: http://www.nabble.com/Domain-object-retains-erroneous-properties-when-in-a-Service-td23001859.html
Hide
Graeme Rocher added a comment -

Calling getMetaClass() now longer causes a transaction to be started

Show
Graeme Rocher added a comment - Calling getMetaClass() now longer causes a transaction to be started
Hide
Jan Rudert added a comment -

Calling getMetaClass() now longer causes a transaction to be started

Could you please double check? I am using Grails 1.1.1 and I am seeing that TransactionService.getMetaClass() still opens a Transaction each time it is called.

Show
Jan Rudert added a comment -
Calling getMetaClass() now longer causes a transaction to be started
Could you please double check? I am using Grails 1.1.1 and I am seeing that TransactionService.getMetaClass() still opens a Transaction each time it is called.
Hide
Jan Rudert added a comment -

Forget my comment, we replaced the responsible code from the ServiceGrailsPlugin with the code from 1.1 because of GRAILS-4644 which occured in 1.1.1. That's why we cannot enjoy the fix for this one here.

Show
Jan Rudert added a comment - Forget my comment, we replaced the responsible code from the ServiceGrailsPlugin with the code from 1.1 because of GRAILS-4644 which occured in 1.1.1. That's why we cannot enjoy the fix for this one here.

People

Vote (1)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: