我正在尝试设置用户案例,其中我有一个通用表单,可以处理所有类型的UploadedFile
用户上传。所以,这是我的设置:
@Entity(name="UploadedForm")
@Table(name="uploaded_file")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)
public class UploadedFile implements Serializable{
/**
*
*/
private static final long serialVersionUID = -6810328674369487649L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
protected Long id;
@Column(name="name")
protected String name = null;
@Column(name="bytes",unique=true)
@Lob
protected byte[] bytes;
@Column(name="type",nullable=false, updatable=false, insertable=false)
protected String type;
@ManyToOne(fetch=FetchType.LAZY, targetEntity=User.class)
@JoinColumn(name="user_id")
protected User user;
@Column(name="date_submitted")
@Temporal(TemporalType.DATE)
protected Date dateSubmitted;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getDateSubmitted() {
return dateSubmitted;
}
public void setDateSubmitted(Date dateSubmitted) {
this.dateSubmitted = dateSubmitted;
}
@PrePersist
@PreUpdate
public void populateDateSubmitted(){
this.dateSubmitted = new java.sql.Date(new java.util.Date().getTime());
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
public String getType() {
return type;
}
}
@Entity(name="Document")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorValue(value="Document")
public class DocumentFile extends UploadedFile {
public void setDateSubmitted(Date dateSubmitted) {
this.dateSubmitted = dateSubmitted;
}
@PrePersist
@PreUpdate
public void populateDateSubmitted(){
this.dateSubmitted = new java.sql.Date(new java.util.Date().getTime());
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
}
@RequestMapping( value="{type}",method=RequestMethod.GET )
public String showForm(ModelMap model, @PathVariable("type") String type){
UploadedFile form = null;
if((model.get("FORM") == null)){
if(type.equals("document")){
form = new DocumentFile();
}
else if( type.equals("image")){
form = new ImageFile();
}
}else{
form = (UploadedFile)model.get("FORM");
if(form.getClass() == DocumentFile.class)
form = (DocumentFile)form;
else if(form.getClass() == ImageFile.class)
form = (ImageFile)form;
}
model.addAttribute("message", "Please select your file and hit submit.");
model.addAttribute("FORM", form);
model.addAttribute("type", type);
return "upload_form";
}
@RequestMapping( method=RequestMethod.POST )
public String processForm(Model model, @RequestParam(value="type") String type, @ModelAttribute(value="FORM") UploadedFile form,BindingResult result, Principal principal) throws FileSaveException, Exception{
if(!result.hasErrors()){
UploadedFile savedFile = null;
try {
// Find the currently logged in user. There has to be a more eloquent way...
String username = principal.getName();
User user = uService.findByName(username);
// Set the associated user to the UploadedFile
form.setUser(user);
if(type.equals("document"))
form = (DocumentFile)form;
else if(type.equals("image"))
form = (ImageFile)form;
// Persist the file
savedFile = this.saveFile(form);
} catch (Exception e) {
FileSaveException fse = new FileSaveException("Unable to save file: " + e.getMessage());
fse.setStackTrace(e.getStackTrace());
throw fse;
}
model.addAttribute("message", "SUCCESS!");
model.addAttribute("FORM", savedFile);
return "upload_success";
}else{
return "upload_form";
}
}
<%@ include file="/WEB-INF/views/includes.jsp" %>
<%@ page session="false" %>
<%@ include file="/WEB-INF/views/header.jsp" %>
<head>
<title>upload</title>
</head>
<body>
<h1>Upload Stuff -</h1>
${message}
<br />
<br />
<form:form commandName="FORM" action="/upload"
enctype="multipart/form-data" method="POST">
<input type="hidden" name="type" value="${ type }"/>
<table>
<tr>
<td colspan="2" style="color: red;"><form:errors path="*"
cssStyle="color : red;" /> ${errors}</td>
</tr>
<tr>
<td>Name :</td>
<td>
<form:input type="text" path="name" />
</td>
</tr>
<tr>
<td>File:</td>
<td>
<form:input type="file" path="bytes" />
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Upload File" />
</td>
</tr>
</table>
</form:form>
<br />
<a href="/">Go home</a>
</body>
<%@ include file="/WEB-INF/views/footer.jsp"%>
我得到的错误是:
无法将对象
UploadedFile
强制转换为DocumentFile
知道为什么吗?
更新:我发现了一种解决方法,即不传递UploadedFile,而是传递我实际想要保留的Concrete类。我还必须删除controller / service / dao方法,并为每个UploadedFile子项创建一个。似乎应该有更好的方法来做到这一点。请提出你的建议。先感谢您! :)
答案 0 :(得分:0)
你的问题看起来更像是关于Spring而不是Hibernate。这样:
@ModelAttribute(value="FORM") UploadedFile form
Spring在转换传入请求时无法知道您希望它创建DocumentFile
UploadedFile
的{{1}}个实例。可以创建自己的ConversionService
,但是为不同的表单创建不同的请求映射可能更容易。像
@RequestMapping(value="/post/uploadedfile", method=RequestMethod.POST )
public String processUploadedFileForm(Model model, @RequestParam(value="type") String type, @ModelAttribute(value="FORM") UploadedFile form,BindingResult result, Principal principal) throws FileSaveException, Exception{
...
}
@RequestMapping(value="/post/documentfile", method=RequestMethod.POST )
public String processDocumentFileForm(Model model, @RequestParam(value="type") String type, @ModelAttribute(value="FORM") DocumentFile form,BindingResult result, Principal principal) throws FileSaveException, Exception{
...
}