java - 在 spring mvc hibernate 应用程序中从字符串转换为 blob 时出错

标签 java spring hibernate jsp spring-mvc

在使用 hibernate 和 jpa 的 spring mvc 应用程序中,我有一个表单需要存储一个文档,其中包括有关文档的元数据,例如提交表单时的当前日期。我已经设置了模型、 Controller 和 jsp,但是当它运行时,当用户单击按钮将文档提交到数据库时,将返回创建或添加 jsp。该错误表明问题在于代码未处理从 String 到 Blob 的转换。我已经注意到 processCreationForm() 方法中代码返回 createOrUpdateDocumentForm.jsp 而不是重定向到列表 JSP 的位置,并且我已将错误消息包含在此帖子的底部。

如何更改下面的代码,以便当用户单击提交按钮时将文档保存到数据库?

这是我的 createOrUpdateDocumentForm.jsp:

<body>
<script>
    $(function () {
        $("#created").datepicker({ dateFormat: 'yy/mm/dd'});
    });
</script>
<div class="container">
    <jsp:include page="../fragments/bodyHeader.jsp"/>
    <c:choose>
        <c:when test="${document['new']}">
            <c:set var="method" value="post"/>
        </c:when>
        <c:otherwise>
            <c:set var="method" value="put"/>
        </c:otherwise>
    </c:choose>

    <h2>
        <c:if test="${document['new']}">New </c:if>
        Document
    </h2>

    <form:form modelAttribute="document" method="${method}"
               class="form-horizontal">
        <div class="control-group" id="patient">
            <label class="control-label">Patient </label>

            <c:out value="${document.patient.firstName} ${document.patient.lastName}"/>
        </div>
        <petclinic:inputField label="Name" name="name"/>
        <petclinic:inputField label="Description" name="description"/>
        <div class="control-group">
            <petclinic:selectField name="type" label="Type " names="${types}" size="5"/>
        </div>
        <td><input type="file" name="content" id="content"></input></td>
        <div class="form-actions">
            <c:choose>
                <c:when test="${document['new']}">
                    <button type="submit">Add Document</button>
                </c:when>
                <c:otherwise>
                    <button type="submit">Update Document</button>
                </c:otherwise>
            </c:choose>
        </div>
    </form:form>
    <c:if test="${!document['new']}">
    </c:if>
    <jsp:include page="../fragments/footer.jsp"/>
</div>
</body>

以下是 Controller 的相关部分:

@RequestMapping(value = "/patients/{patientId}/documents/new", method = RequestMethod.GET)
public String initCreationForm(@PathVariable("patientId") int patientId, Map<String, Object> model) {
    Patient patient = this.clinicService.findPatientById(patientId);
    Document document = new Document();
    patient.addDocument(document);
    model.put("document", document);
    return "documents/createOrUpdateDocumentForm";
}

@RequestMapping(value = "/patients/{patientId}/documents/new", method = RequestMethod.POST)
public String processCreationForm(@ModelAttribute("document") Document document, BindingResult result, SessionStatus status) {
    document.setCreated();
    //THE FOLLOWING LINE PRINTS OUT A VALID DATE FOR document.getCreated()
    System.out.println("document.getCreated() is: "+document.getCreated());
    new DocumentValidator().validate(document, result);
    if (result.hasErrors()) {
        System.out.println("result.getFieldErrors() is: "+result.getFieldErrors());
        //THIS IS BEING RETURNED BECAUSE result.getFieldErrors() RETURNS WHAT IS BEING  
        //SHOWN AT THE BOTTOM OF THIS POSTING, BELOW  
        return "documents/createOrUpdateDocumentForm";
    }
    else {
        this.clinicService.saveDocument(document);
        status.setComplete();
        return "redirect:/patients?patientID={patientId}";
    }
}

这是模型,它是 Document.java 的一部分:

@Entity
@Table(name = "documents")
public class Document {
    @Id
    @GeneratedValue
    @Column(name="id")
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "client_id")
    private Patient patient;

    @ManyToOne
    @JoinColumn(name = "type_id")
    private DocumentType type;

    @Column(name="name")
    private String name;

    @Column(name="description")
    private String description;

    @Column(name="filename")
    private String filename;

    @Column(name="content")
    @Lob
    private Blob content;

    @Column(name="content_type")
    private String contentType;

    @Column(name = "created")
    private Date created;

    public Integer getId(){return id;}
    public void setId(Integer i){id=i;}

    protected void setPatient(Patient patient) {this.patient = patient;}
    public Patient getPatient(){return this.patient;}

    public void setType(DocumentType type) {this.type = type;}
    public DocumentType getType() {return this.type;}

    public String getName(){return name;}
    public void setName(String nm){name=nm;}

    public String getDescription(){return description;}
    public void setDescription(String desc){description=desc;}

    public String getFileName(){return filename;}
    public void setFileName(String fn){filename=fn;}

    public Blob getContent(){return content;}
    public void setContent(Blob ct){content=ct;}

    public String getContentType(){return contentType;}
    public void setContentType(String ctype){contentType=ctype;}

    public void setCreated(){created=new java.sql.Date(System.currentTimeMillis());}
    public Date getCreated() {return this.created;}

    @Override
    public String toString() {return this.getName();}
    public boolean isNew() {return (this.id == null);}

}

上面的代码可以编译,但是当用户输入信息上传文档后按下提交按钮时,会返回相同的添加或更新表单,而不是重定向到摘要页面。这从上面的 Controller 方法表明,即使 system.out.println 检查的错误都不为 true,result.haserrors 也为 true。 eclipse控制台没有显示错误。然而 result.getFieldErrors() 打印出以下内容:

[
Field error in object 'document' on field 'content': 
rejected value [mydocname.txt]; 
codes [typeMismatch.document.content,typeMismatch.content,typeMismatch.java.sql.Blob,typeMismatch]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: 
codes [document.content,content]; 
arguments []; default message [content]]; 
default message 
[
Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Blob' for property 'content'; 
nested exception is java.lang.IllegalStateException: 
Cannot convert value of type [java.lang.String] to required type [java.sql.Blob] for property 'content': 
no matching editors or conversion strategy found
]
]

最佳答案

首先,您的表单缺少标签 enctype="multipart/form- data", 如果它仍然不起作用,您可以考虑使用 MultipartFile界面

更新

您可以阅读spring documentation ,这真的很简单。 现在,要将其应用到您的情况,您可以按照本教程进行操作:Saving/Retreving BLOB object in Spring 3 MVC and Hibernate

关于java - 在 spring mvc hibernate 应用程序中从字符串转换为 blob 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20508536/

相关文章:

java - Hibernate Multi-Tenancy 测试因 NPE 失败

java - XMLPullParser 特殊字符

java - Maven中parent标签的含义

java - 从属性文件构建 java 列表

java - 修改 hibernate 文件以满足我的需要

oracle - 使用 Oracle Streams AQ 在 Spring MDB 中共享 JMS 和 Hibernate 事务?

java - 执行 ftp 时出现错误 "javax.net.ssl.SSLException: 530 Please login with USER and PASS"

java - onRequestPermissionResult 永远不会从 Activity 调用

java - 使用 Spring RestTemplate 检索 cookie

mysql - 适用于 H2 和 MySQL 的相对时间查询