2011-01-11 5 views
15

domanda iniziale (AGGIORNATO IN BASSO)problema strano quando vincolante un elenco dinamico

sto usando un elenco AutoPopulatingList a instatiate un oggetto invocando un costruttore con alcuni parametri. Qualcosa come il codice qui sotto. L'avevo usato prima senza problemi ma non riesco a farlo funzionare ora.

public class Tree { 
    ... 
    private List<Node> nodes = new AutoPopulatingList<Node>(new ElementFactory<Node>() { 
     @Override 
     public Node createElement(final int index) throws ElementInstantiationException { 
      //call custom controller 
      return new Node(index, ...other params); 
     }  
    }); 
    ... 
    //getters & setters 
} 

L'oggetto viene mappato in un controllore come param attributo di modello (@ModelAttribute Tree). Così mando in forma Valori come:

nodes[0].field1 = some value 
nodes[1].field2 = other value 

Ma quando mando questi parametri primavera non può un'istanza dell'oggetto Node perché è alla ricerca di un costruttore senza params per Node oggetto, e viene generata un'eccezione simile al seguente:

org.springframework.beans.NullValueInNestedPathException: di proprietà non valido 'nodi' della classe bean [... Nodo]: Impossibile creare un'istanza tipo di proprietà [... Nodo] per auto-crescere percorso proprietà nidificato: java.lang .InstantiationException: ... Node.()

Se aggiungo un costruttore senza parametri alla classe Node non c'è errore, ma quando invio nodes[0] viene invocato Node() invece di utilizzare il ElementFactory fornito.

La cosa strana è che se faccio nel controller treeObject.getNodes().get(0), il costruttore richiamato è quello con parametri (come dovrebbe essere).

Sto usando Spring 3.0.4.RELEASE.

Qualcuno sa perché questo può accadere? Può essere un bug?

Grazie.


UPDATE

Ho costruire un'implementazione personalizzata di un elenco simile a AutoPopulatingList per verificare se questo è stato un problema di AutoPopulatingList, ma succede lo stesso comportamento. L'implementazione sovrascrive solo:

public Node get(int index) { 
    //here just creates the object it it doesn't exist in the position 
} 

Quindi il problema è il motivo per cui quando lo faccio in un controllore:

public String controllerMethod(
@ModelAttribute Tree tree, BindingResult result, Model model){ 
    ... 
} 

e mando i nodi [0] .something come non c'è alcun oggetto nel posizione 0 dell'indice deve istanziare l'oggetto. Ma il problema è che è invocato il costruttore Node() prima di richiamare tree.get (0). Quindi, perché Spring invoca il costruttore predefinito? Come posso forzarlo a usare tree.get (0) per istanziare l'oggetto invece di Node()?

+0

Hai detto: "L'avevo usato prima senza problemi ma non riesco a farlo funzionare ora". - cosa hai cambiato? – Ralph

+0

Per me sembra, se qualcuno rimuove l'elenco dei nodi da Tree prima che Spring inizi a popolarlo. – Ralph

+0

@ Ralph Ho solo cambiato la versione Spring (anche se era la Spring 3) e ovviamente l'oggetto perché l'ho usato in altri progetti. Ma non ho cambiato il modo in cui lo uso. – Javi

risposta

15

L'ho risolto disabilitando i percorsi autogrownested nel raccoglitore, quindi questo consente l'elenco di Autopopulating che si occuperà della crescita automatica con la propria factory.

@InitBinder 
public void initBinder(WebDataBinder binder){ 
    binder.setAutoGrowNestedPaths(false); 
}