Grails supports domain classes as properties of command objects out of the box. I can use a domain class Stuff with a command StuffCommand, but not if Stuff is an abstract class.
Stuff.groovy
abstract class Stuff{
}
StuffCommand.groovy
class StuffCommand{
Stuff stuff
}
ExampleController.groovy
class ExampleController{
def doStuffWithStuff(StuffCommand stuffCmd){
render stuffCmd.stuff ? stuffCmd.stuff as JSON : ''
}
}
Then, the request http://server:port/ctx/example/doStuffWithStuff?stuff=123 will not get the record #123 out of the stuff table from my database. I love the concise nature of that approach. The query on the database either does not take place or fails silently.
The following workaround helps a little, though:
Create a class that converts ValueConverter for the abstract comain class. The class name must end with ValueConverter, other than that you can name it at will, for instance IdStringToStuffValueConverter.
IdStringToStuffValueConverter
import org.grails.databinding.converters.ValueConverter
class IdStringToStuffValueConverter implements ValueConverter{
@Override
boolean canConvert(Object value) {
value instanceof String || value instanceof Integer || value instanceof Long
}
@Override
Object convert(Object value) {
return Stuff.get(value.toLong())
}
@Override
Class<?> getTargetType() {
return Stuff
}
}
Now I can fire above request and the controller will hit the database again during data binding. But the following does still not work as expected:
ExampleController.groovy
class ExampleController{
def doStuffWithStuff(Stuff stuff){
render stuff ? stuff as JSON : ''
}
}
During this action no database queries take place, hence the workaround does not cover this case. How can I use abstract domain classes as command objects?