views:

42

answers:

2

Following grails domain class:

class MyClass {
  Map myMap
}

Now for myMap, grails automatically creates a new table for the elements in the map. However if I add elements which are too long (e.g. 1024 characters), I get a DB error.

Can I somehow tell grails to make the respective column in myMap's table big enough to allow for larger Strings, or do I have to do this manually in the DB?

I already tried

static constraints = {
  myMap(maxSize:1024)
}

which doesn't work (as expected because maxSize should refer to the Map's values and not to the Map itself).

If not via constraints, maybe there's a way to do it via

static mapping { ... }

?

A: 

what are you trying to accomplish? Is there always the same number of things in the map? If there is you should define those properties on your class.

You can see the problem with your current approach -- there is no way to figure out what might be in the map until runtime, so how can grails possibly create a columns for it? Im surprised it even worked to begin with...

hvgotcodes
Actually, maps are supported just fine. The keys must be Strings. However I think you would need to modify the underlying hibernate config file to tweak the table created for the map.See http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20(GORM).html#5.2.4%20Sets%2C%20Lists%20and%20Maps (section 5.2.4 Sets, Lists and Maps - I'm having trouble getting the link right.).
Matt Lachman
+2  A: 

An alternative approach I used successfully was to push the map out into a collection of a collaborator domain class.

class DynaProperty {
    String name
    String value

    static belongsTo = MyClass
    static constraints = {
        value(maxSize:4000)  //Or whatever number is appropriate
    }
}

And then in MyClass:

class MyClass {
    static hasMany = [dynaProperties:DynaProperty]
}

This is almost a map, and it gives you the ability to use dynamic finders to pull up an individual entry.

Matt Lachman
Thanks, that's the way I finally did it. I tried to overwrite the setter so that you're able to pass a Map as a parameter directly, but this didn't work - e.g. public void setdynaProperties(Map map) { map.each { this.addToDynaProperties(name:it.key.toString(), value:it.value.toString()) } }. At least it didn't work using the Constructor.
werner5471
Cool, I'm glad the overall solution worked for you. I'm curious what the error was with your setter? I know I've had issues with trying to "fake" a property with a typed method signature and that if I used "def" (instead of "public void") it tended to work. But that may apply more to getters than setters.
Matt Lachman