Search code examples
grailsmaster-detail

Grails : Problems with Lazy List


I have a web page that allows the user to enter data which will form a Master / Detail relationship when stored to my database. I submit the data to a Grails controller that binds the data in to a Command Object. As I do not know how many "detail" rows will be submitted, I am attempting to use a Lazy List to bind the detail data to. I am failing spectacularly.

My command object looks like :

String title    
List testItems = LazyList.decorate(new ArrayList(),
                                   FactoryUtils.instantiateFactory(VocabQuestion.class));

When I submit the form I get the following exception :

| Error 2013-06-04 22:42:54,068 [http-bio-8080-exec-4] ERROR errors.GrailsExceptionResolver  - MissingMethodException occurred when processing request: [POST] /*****/vocabulary/save - parameters:
testItems[1].question: Q2
title: Test
testItems[0].answer: A1
testItems[0].question: Q1
testItems[0].vocabulary_test_id: 
testItems[1].answer: A2
create: Create
No signature of method: vocabularytest.TestCreationCommand.propertyMissing() is applicable for argument types: () values: []
Possible solutions: propertyMissing(java.lang.String). Stacktrace follows:
Message: No signature of method: vocabularytest.TestCreationCommand.propertyMissing() is applicable for argument types: () values: []
Possible solutions: propertyMissing(java.lang.String)
    Line | Method
->>  102 | <init>    in vocabularytest.TestCreationCommand

This exception happens very early on in the objects lifecycle, presumeably as Grails tries to bind the data to it.

If I define my Command Object as :

String title    
List testItems = [new VocabQuestion()]

and only submit 1 detail record from the form, then everything works as expected.

Where am I going wrong?

EDIT My VocabQuestion domain class is

package vocabularytest
class VocabQuestion {

    static constraints = {

    }

    static belongsTo = [vocabularyTest: VocabularyTest]

    String question
    String answer

}

Solution

  • I found an answer ( might not be THE answer but it works )

    I used the LazyList syntax that is native in later Groovy versions as follows.

    List testItems = [].withLazyDefault {new VocabQuestion()}