【发布时间】:2014-01-02 10:10:19
【问题描述】:
我正在使用jpa 和MySQL 在spring 中开发一个文档管理应用程序。该应用程序当前正在接受来自用户 Web 表单 createOrUpdateDocumentForm.jsp 的文档及其元数据到控制器 DocumentController.java。但是,数据并未进入MySQL 数据库。有人可以告诉我如何更改我的代码,以便将文档及其元数据存储在底层数据库中吗?
数据流(包括pdf文档)似乎要经过以下对象:
createOrUpdateDocumentForm.jsp //omitted for brevity, since it is sending data to controller (see below)
Document.java
DocumentController.java
ClinicService.java
JpaDocumentRepository.java
The MySQL database
我将每个对象的相关部分总结如下:
jsp 在DocumentController.java 中触发以下方法:
@RequestMapping(value = "/patients/{patientId}/documents/new", headers = "content-type=multipart/*", method = RequestMethod.POST)
public String processCreationForm(@ModelAttribute("document") Document document, BindingResult result, SessionStatus status, @RequestParam("file") final MultipartFile file) {
document.setCreated();
byte[] contents;
Blob blob = null;
try {
contents = file.getBytes();
blob = new SerialBlob(contents);
} catch (IOException e) {e.printStackTrace();}
catch (SerialException e) {e.printStackTrace();}
catch (SQLException e) {e.printStackTrace();}
document.setContent(blob);
document.setContentType(file.getContentType());
document.setFileName(file.getOriginalFilename());
System.out.println("----------- document.getContentType() is: "+document.getContentType());
System.out.println("----------- document.getCreated() is: "+document.getCreated());
System.out.println("----------- document.getDescription() is: "+document.getDescription());
System.out.println("----------- document.getFileName() is: "+document.getFileName());
System.out.println("----------- document.getId() is: "+document.getId());
System.out.println("----------- document.getName() is: "+document.getName());
System.out.println("----------- document.getPatient() is: "+document.getPatient());
System.out.println("----------- document.getType() is: "+document.getType());
try {System.out.println("[[[[BLOB LENGTH IS: "+document.getContent().length()+"]]]]");}
catch (SQLException e) {e.printStackTrace();}
new DocumentValidator().validate(document, result);
if (result.hasErrors()) {
System.out.println("result.getFieldErrors() is: "+result.getFieldErrors());
return "documents/createOrUpdateDocumentForm";
}
else {
this.clinicService.saveDocument(document);
status.setComplete();
return "redirect:/patients?patientID={patientId}";
}
}
当我通过jsp 中的web 表单向controller 提交文档时,System.out.println() 代码中的System.out.println() 命令输出以下内容,这表明数据实际上正在发送到服务器:
----------- document.getContentType() is: application/pdf
----------- document.getCreated() is: 2013-12-16
----------- document.getDescription() is: paper
----------- document.getFileName() is: apaper.pdf
----------- document.getId() is: null
----------- document.getName() is: apaper
----------- document.getPatient() is: [Patient@564434f7 id = 1, new = false, lastName = 'Frank', firstName = 'George', middleinitial = 'B', sex = 'Male', dateofbirth = 2000-11-28T16:00:00.000-08:00, race = 'caucasian']
----------- document.getType() is: ScannedPatientForms
[[[[BLOB LENGTH IS: 712238]]]] //This indicates the file content was converted to blob
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);}
}
从DocumentController 调用的ClinicService.java 代码是:
private DocumentRepository documentRepository;
private PatientRepository patientRepository;
@Autowired
public ClinicServiceImpl(DocumentRepository documentRepository, PatientRepository patientRepository) {
this.documentRepository = documentRepository;
this.patientRepository = patientRepository;
}
@Override
@Transactional
public void saveDocument(Document doc) throws DataAccessException {documentRepository.save(doc);}
JpaDocumentRepository.java中的相关代码为:
@PersistenceContext
private EntityManager em;
@Override
public void save(Document document) {
if (document.getId() == null) {this.em.persist(document);}
else {this.em.merge(document);}
}
最后,创建数据库的SQL代码的相关部分包括:
CREATE TABLE IF NOT EXISTS documenttypes (
id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(80),
INDEX(name)
);
CREATE TABLE IF NOT EXISTS patients (
id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(30),
middle_initial VARCHAR(5),
last_name VARCHAR(30),
sex VARCHAR(20),
date_of_birth DATE,
race VARCHAR(30),
INDEX(last_name)
);
CREATE TABLE IF NOT EXISTS documents (
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
client_id int(4) UNSIGNED NOT NULL,
type_id INT(4) UNSIGNED,
name varchar(200) NOT NULL,
description text NOT NULL,
filename varchar(200) NOT NULL,
content mediumblob NOT NULL,
content_type varchar(255) NOT NULL,
created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (client_id) REFERENCES patients(id),
FOREIGN KEY (type_id) REFERENCES documenttypes(id)
);
我对此代码做了哪些更改,以便它使用jpa 将document 保存在MySQL 数据库的documents 表中?
【问题讨论】:
-
我假设没有错误并且其他数据已提交到数据库?
-
@user2310289 在此操作期间,我没有在 Eclipse 控制台中看到错误。此应用程序中的另一个模块确实提交数据以将人员添加到数据库,但添加文档模块不提交任何数据。唯一的错误是在 tomcat 服务器中加载应用程序时出现的,但应用程序确实加载了,然后当前问题中的代码运行而没有抛出任何错误。如果您认为在加载应用程序期间发生的错误是相关的,您可以在此帖子中查看它:stackoverflow.com/questions/20622746/…
-
“唯一的错误是在 tomcat 服务器中加载应用程序时出现的” 哪个是?另外,您在 jsp 上的表单是否具有此属性:
enctype="multipart/form-data" -
在尝试给出答案之前,我想请您发送
em.flush()并告诉我们这是否有效。 -
另外,您能否指定您正在使用的 JPA 提供程序,Hibernate?同时,作为一个假设,我建议你尝试这样的
@Lob组合:你可以使用byte[]类型而不是Blob类型。如果不想加载这个,可以添加注解@Basic(fetch = FetchType.LAZY)。所以一切看起来像:@Column(name="content") @Lob @Basic(fetch = FetchType.LAZY) private byte[] content;
标签: java spring hibernate spring-mvc jpa