On a Grails 2.1.0 I am trying to dynamically updating a field on a domain class. The object gets binded and it looks fine, until the save method is called, which throws the following exception:
java.lang.IllegalStateException: Cannot make an immutable entity modifiable.
try {
def bindParams = [:]
bindParams."$paramsFieldName" = "$paramsValue"
def domainClass = grailsApplication.domainClasses.find { it.clazz.simpleName == paramsDomain }.clazz
def objectInstance = domainClass.findById(paramsId)
objectInstance."$paramsFieldName" = "$paramsValue"
bindData(objectInstance, bindParams)
objectInstance.save(flush:true ,failOnError:false)
return objectInstance
}
catch (Exception ex) {
log.error ex
return null
}
I tried to bind the field using direct assigment and worked well.
objectInstance."$paramsFieldName" = convertToType( fieldType.name,paramsValue)
but then I need to handle the type conversion for each case (I assume). What I need is the BindDynamicMethod handles the binding for me. What happens to the object when binding it using the BindDynamicMethod that makes is immutable?. Or what am I doing wrong that is causing it?
=========================================================
PARTIALLY SOLVED
It turned out that this was happening on some of the domains, but some that were using cache on their mapping was throwing this exception.
class UploadSettings {
String profile = "default"
String displayName
String name
String value
String defaultValue
static mapping = {
//cache usage:'read-only'
}
}
So I guess now my question is if a domain is using cache , why cant we update its value? Or how can we do that? Is there a way to capture if the domain is immutable?
Thanks
Yes by setting it to read-only you are making the object immutable as the error says, IMHO this is misleading as we are in the context of caching but there is some rationale behind this.
If you need caching at the domain level then setting it to read-write should do the trick
See cache usages