【问题标题】:nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type嵌套异常是 java.lang.IllegalStateException:无法将 [java.lang.String] 类型的值转换为所需类型
【发布时间】:2012-05-17 02:22:29
【问题描述】:

我在尝试提交表单时收到以下验证错误。使用 Document.java 中的值填充的下拉框会出现此错误:

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

我的映射有问题吗?

Document.java 映射

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

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

DocumentRevision.java 映射

    @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;
}

两个表的关系是,多个DocumentRevisions可以有相同的DocumentNumber,而单个DocumentRevision只能有一个文件编号

感谢您的帮助

/D

编辑

我正在使用 spring 3.0 和 hibernate 3。Here 是我最近的一个线程,其中包括控制器和 jsp 页面。

编辑 2

这是应该将 document_number 保存到 DocumentRevision 中的 DAO 实现方法

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

编辑 3

我相信这是应该记录 document_number 的代码部分。我必须在 .POST 方法的某处使用“documentNumberList”吗?在那种情况下我该怎么做?

部分控制器:

@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";  
}

更新

我已将以下内容添加到我的控制器中:

    /**
 * 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());
}

我现在收到 NullPointerException:

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

为什么 PropertyEditor 中的 getter 没有得到值?

编辑 4

retrieveDocumentNumber(text) 方法:

    public Document retrieveDocumentNumber(String text){
    return (Document) this.sessionFactory.getCurrentSession().get(Document.class, text);
}

【问题讨论】:

  • 你说的是哪种下拉框?您使用的框架是什么?
  • @rolve 很抱歉没有提供该信息。请看我的编辑
  • 我认为问题不在于 ORM 映射。根据错误消息,有些东西试图将字符串放入Document.document_number。执行此操作的代码在哪里?
  • @rolve 我添加了 DAO 方法,该方法应该使用从保管箱中选择的 document_number 保存新的 documentRevision
  • 调用DAO方法时,DocumentRevision对象已经更新了,对吧?我认为错误发生在此之前,当框架尝试设置 document_number 字段时。

标签: java spring hibernate orm annotations


【解决方案1】:

Spring WebDataBinder 无法将 String document_number 转换为 Document 实例时 填充 documentRevision 模型属性。你有两种可能:

  • 使用可以处理转换的PropertyEditor 初始化WebDataBinder。最直接,但仅适用于此控制器。

  • 注册Converter&lt;String, Document&gt;

如果选择第一个,用@InitBinder注解注解控制器方法并注册 属性编辑器。似乎您只需要通过 document_number 从数据库中获取文档。请参阅参考文档中的Customizing WebDataBinder initatization

编辑

将文档映射到/从 Ids 字符串的属性编辑器示例。

/**
 * 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()) : "";
    }
}

第二种方法,看Validation, Data Binding, and Type Conversion看看 如何在Spring ConversionService中创建和注册Converter

【讨论】:

  • 这是写控制器方法的正确方法吗? ` @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(Document.class, new DocumentEditor()) }` 如何编写 DocumentEditor?
  • 我在答案中添加了一个使用 documentService 获取文档的示例
  • 当我进入添加页面时出现此错误:" java.lang.NumberFormatException: For input string: "DOC 9991783478"" 你知道我该如何解决这个问题吗?
  • 需要在 setAsText() 方法中将 document_number 字符串转换为 Document。我假设您在示例代码中使用 Longs 作为 Document PK(这只是一个示例,不用于逐字复制))。如果您对 document_number 使用字符串键,请不要将其转换为 long (Long.parseLong(...))。
  • 你介意告诉我怎么做吗?恐怕我不完全了解属性编辑器的工作原理。我应该初始化“String id;”吗?但那我给 id 什么值呢?谢谢你的帮助!我真的很感激
猜你喜欢
  • 1970-01-01
  • 2020-01-05
  • 1970-01-01
  • 2021-09-02
  • 2020-07-02
  • 2021-06-25
  • 2017-01-28
  • 2019-08-23
  • 2019-11-05
相关资源
最近更新 更多