I'm trying to serialize a Grails domain class instance into Memcached just after updating the domain instance by normal data binding.
When I'm doing this, I'm getting NotSerializableException saying Caused by NotSerializableException: org.codehaus.groovy.grails.web.json.JSONObject which looks like one of the field inside the domain instance is not serializable which is not implementing Serializable interface which is of type JSONObject of Groovy.
But, my domain class does not having such a field. This clearly states that some thing is being set by Grails databinding, since this serialization is working fine if I freshly get a instance.
So, is there any way of knowing that which field is actually failed to serialize?
Related
This is almost identical to this old question: Dynamic define the inList constraint using database query which was essentially unaddressed, perhaps there have been advances in the years since that was asked.
I'd like to populate the inList parameter of a domain attribute with values from another domain. Due to auto-generated views (scaffolding, filterpane), this needs to come from inList rather than a custom validator.
class MyDomain {
String someValue
static constraints = {
someValue(nullable: true, maxSize: 50, inList: SomeOtherDomain.list()*.name)
}
}
This gives the following error on startup:
Caused by: java.lang.IllegalStateException: Either class [thepackage.SomeOtherDomain] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
I know, the "correct" way to handle this is to make someValue an instance of SomeOtherDomain instead of just storing the name, but that doesn't quite fit. We want to be able to delete an instance of SomeOtherDomain without breaking the saved value of the owning domain... the domain with the deleted value will be invalid going forward, and would have to be updated before saving, but archived/locked records will still exist and can be displayed.
You can specify value lists for filterpane like this:
<filterpane:filterPane domain="MyObject" filterPropertyValues="${['someValue':[values: SomeOtherDomain.list().collect{it.name}]]}" />
And then just use a custom validator to actually validate. I'm not sure what scaffolding might use the inList but easy enough to get around that if you're OK with replacing a few scaffolded pages with static ones.
To add a username "lastUpdatedBy" property (along with some other std properties) to several domain classes I created a trait. Everything works fine to the database, but EhCache disk storage gives a NotSerializableException on springSecurityService. I have
def springSecurityService
in order to get the principal.username.
Is there a way to designate the service as transient (static transients=[] doesn't seem to help), or am I at a dead end? Referencing a service from within a domain class is a bit dodgy anyway, but what is a better, workable way to get the username just before saving?
Ok, I figured this out. One of the domain classes had a composite key and was therefore tagged to implement Serializable. Once this was converted to maintain the usual id field and "implements Serializable" was removed, the problem went away.
Just declare your the field as a transient field.
class MyDomain {
// other stuff omitted
transient SpringSecurityService springSecurityService
}
This will do the job when it come to serialization.
I have a command object that I want to convert into a domain object.
However, the object I want to convert the command object into may be one of two domain classes (they're both derived classes), and I need to do it in a service (which is where, based on other data, I decide which type of object it should be bound to). Is this possible and what's the best way to do this? bindData() only exists in a controller.
Do I just have to manually map command object parameters to the appropriate domain object properties? Or is there a faster/better way?
If the parameters have the same name, then you can use this question to copy the values over. A quick summary can be as follows.
Using the Grails API
You can cycle through the properties in a class by accessing the properties field in the class.
object.properties.each { property ->
// Do something
}
You can then check to see if the property is present in the other object.
if(otherObject.hasProperty(property) && !(key in ['class', 'metaClass']))
Then you can copy it from one object to the other.
Using Commons
Spring has a really good utility class called BeanUtils that provides a generic copy method that means you can do a simlple oneliner.
BeanUtils.copyProperties(object, otherObject);
That will copy values over where the name is the same. You can check out the docs here.
Otherwise..
If there is no mapping between them, then you're kind of stuck because the engine has no idea how to compare them, so you'll need to do it manually.
I'm trying to customize my errors mesages. Firstly, I want to get message key on output as an error, for example: package.Subpage.title.nullable.
To gain this goal I've deleted all message.properties bundles from my application but I still get something like this on output:
Property [title] of class [class package.Subpage] cannot be blank
I've got properties of FieldError class to see if it's implemented there and I've noticed that this class has property:
defaultMessage=Property [{0}] of class [{1}] cannot be blank
Of course I know that there is a pattern for message key which looks like class.property.(blank or nullable or whatever constraint set) and I can override every message, but my main goal is to have full control on this how message key, message value and default message look like.
Question: Is there any way to define default message and message key for errors in grails?
You can implement your own Spring MessageSource, then wire that into Grails:
MessageSource JavaDoc
Spring Refence - Internationalization using MessageSource
Using the Spring Bean DSL in Grails
In my Grails app, I'm using the Searchable plugin for searching/indexing. I want to write a Compass/Lucene query that involves multiple domain classes. Within that query when I want to refer to the id of a class, I can't simply use 'id' because all classes have an 'id' property. Currently, I work around this problem by adding the following property to a class Foo
public Long getFooId() {
return id
}
static transients = ['fooId']
Then when I want to refer to the id of Foo within a query I use 'fooId'. Is there a way I can provide an alias for a property in the searchable mapping rather than adding a property to the class?
You can give a more specific name to your id property. See this page for how to do this.
I finally discovered that this is the way to do it:
static searchable = {
id: name 'fooId'
}
Thanks! This would work really well, that is, if I could get past the OOM errors the app server seems to throw each time Searchable plugin is installed. These are bubbling up via :
org.compass.gps.CompassGpsException: Failed to index, execution exception; nested exception is java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: Java heap space
Has anyone configured their Searchable.groovy in grails-app/conf to perform a strict file:/// or mmap:// only configuration using no heap, and indexing say once or twice per day? Search is beyond a nice to have - but the cost of using the database mirroring in Grails (with Oracle 10g) seems memory intensive.
Really small amount of domains to search (4) small database, maybe 1-2gb for this application.