Reputation: 323
I needed a domain class that held a list of Strings
. It seems fairly well-known that GORM can't handle this, so I've worked around it. At first I tried using getters and setters in the domain class, but that caused problems. Then I found on Stack Overflow a way to use afterLoad()
and beforeValidate()
to rewrite properties as shown below. This has worked well to allow me to turn the List
into a String
for persistence and back to a List
for use in the app.
class Entries {
// persisted to database
String _entry
// exposed to app
List entry
static transients = ['entry'] //don't try to persist the List
def afterLoad() {
// split the String from the database into a List
entry = _entry?.split('\\|')
}
def beforeValidate() {
// join the List into a String for persisting
_entry = entry.join('|')
}
static constraints = {
_entry maxSize:4000
}
}
This works fine programmatically. The only problem is that the Grails scaffolding can't deal with this, even if I try to enter a pipe-delimited string. I understand the reason why is that the scaffolding creates a form field for _entry
, so entry
is null when it tries to save the object. And beforeValidate()
relies on a List of Strings to work.
I tried to get around this in the controller, by setting params.entry = params._entry
, prior to the call to new Entries(params)
. [I recognize that this is not a perfect solution, but this was my first pass at getting the form working.] And then I added a test in beforeValidate()
to set entry = _entry
if entry
was null
. Basically:
EntriesController.groovy:
params.entry = params._entry // I added this line
def entriesInstance = new Entries(params)
Entries.groovy:
def beforeValidate() {
if( entry == null ) entry = _entry // I added this line
_entry = entry.join('|')
}
I thought that would allow me to enter pipe-delimited strings into the scaffolded Create Entries form and get something into the database.
To my surprise, though, I found that both entry
and _entry
were null
in beforeValidate()
, even though I printed and verified that params
contained both keys in the controller. I don't understand why this happens. How did my adding a new key to params
result in nulls arriving in the domain class?
The follow-up question is, of course, what's the right way to make the scaffolded Create Entries form accept a pipe-delimited String that makes it into the database?
Upvotes: 1
Views: 1442
Reputation: 12228
I needed a domain class that held a list of Strings. It seems fairly well-known that GORM can't handle this, so I've worked around it.
I don't agree with you here
class Xyz {
static hasMany = [entries: String]
}
Should create a seperate table to hold your list of strings (It will actually be a Set). Here are the docs
Upvotes: 2