Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type

I am getting the following validation error when I try to submit my form. The dropdown box populated with values from Document.java gives this error:

Failed to convert property value of type java.lang.String to required type 
testapp.domain.Document for property document_number; nested exception is 
java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] 
to required type [testapp.domain.Document] for property document_number: no matching 
editors or conversion strategy found

Is there something wrong with my mapping?

Document.java mapping

    @OneToMany(mappedBy="document_number", cascade = CascadeType.ALL)
private Set<DocumentRevision> documentRevisions;

public void setDocumentRevisions(Set<DocumentRevision> documentRevisions){
    this.documentRevisions = documentRevisions;
}

DocumentRevision.java mapping

    @ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="DOCUMENT_NUMBER")
private Document document_number; 

public void setDocument_number(Document document_number){
    this.document_number = document_number;
}

public Document getDocument_number(){
    return document_number;
}

The relationship between the two tables is that several DocumentRevisions can have the same DocumentNumber but a single DocumentRevision can only have one DocumentNumber

Thank you for your help

/D

Edit

I am using spring 3.0 and hibernate 3. Here is a recent thread by me which includes the controller and jsp page.

Edit 2

Here is the DAO Implementation method that is supposed to save the document_number into DocumentRevision

    public void saveDocumentRevision(DocumentRevision documentRevision) {
    this.sessionFactory.getCurrentSession().save(documentRevision); 
}

Edit 3

I believe this is the part of the code where document_number should be recorded. Do I have to use "documentNumberList" somewhere in the .POST method? How would I do that in that case?

part of controller:

@RequestMapping(value="/add", method=RequestMethod.GET)
public String getDocumentRevision(Model model) {
DocumentRevision documentRevision = new DocumentRevision();
model.addAttribute("documentRevisionAttribute", documentRevision);
model.addAttribute("documentNumberList", documentService.retrieveAllDocumentNumbers());

return "new-documnent-revision";
}


@RequestMapping(value="/add", method=RequestMethod.POST)
public String postDocumentRevision(@ModelAttribute("documentRevisionAttribute") @Valid DocumentRevision documentRevision, BindingResult result) {

if(result.hasErrors()){
    return "new-document-revision";
}

documentRevisionService.createDocumentRevision(documentRevision);
return "redirect:/testapp/document-revision/list";  
}

Update

I have added the following to my controller:

    /**
 * Property editor to map Documents from documents IDs.
 */

 class DocumentPropertyEditor extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        Document value =  documentService.retrieveDocumentNumber(text);
        setValue(value);
    }

    @Override
    public String getAsText() {
        Document d = (Document) getValue();
        return d != null ? String.valueOf(d.getDocumentNumber()) : "";
    }

}


@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Document.class, new DocumentPropertyEditor());
}

I am now getting a NullPointerException:

java.lang.NullPointerException
testapp.controller.DocumentRevisionController$DocumentPropertyEditor.getAsText(DocumentRevisionController.java:59)

Why isn't the getter in th PropertyEditor getting a value?

Edit 4

the retrieveDocumentNumber(text) method:

    public Document retrieveDocumentNumber(String text){
    return (Document) this.sessionFactory.getCurrentSession().get(Document.class, text);
}
like image 561
dlinx90 Avatar asked May 08 '12 15:05

dlinx90


1 Answers

Spring WebDataBinder fail to convert the String document_number to a Document instance when populating the documentRevision model attribute. You have two posibilities:

  • Initialize the WebDataBinder with a PropertyEditor that can handle the conversion. Most direct, but work only for this controller.

  • Register a Converter<String, Document>

if choose the first, annotate a controller method with @InitBinder annotation and register the property editor. Seems like you only need to fetch the document from database by document_number. See Customizing WebDataBinder initatization on reference documentation.

Edit

Property editor example to map Documents to/from Ids Strings.

/**
 * Property editor to map Documents from documents IDs.
 */
 class DocumentPropertyEditor extends PropertyEditorSupport {

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        Long id = Long.parseLong(text);
        Document value = id == 0 ? null : documentService.get(id);
        setValue(value);
    }

    @Override
    public String getAsText() {
        Document d = (Document) getValue();
        return d != null ? String.valueOf(d.getId()) : "";
    }
}

For the second approach, look at Validation, Data Binding, and Type Conversion to see how to create and register a Converter in the Spring ConversionService.

like image 66
Jose Luis Martin Avatar answered Oct 27 '22 15:10

Jose Luis Martin