2012-02-26 19 views
1

すべてのタイプのUploadedFileユーザーアップロードを処理できる1つの汎用フォームがあるユーザーケースを設定しようとしています。クラス階層ごとの単一テーブルの子クラスへの親クラスのキャスト

@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"%> 

そして、私は取得していますエラーは次のとおりです:だから、ここに私のセットアップがある

DocumentFile

に任意のアイデアをオブジェクトUploadedFileをキャストすることができません

どうして?

UPDATE:私は実際に永続化したいコンクリートクラスを渡す代わりに、UploadedFileを回避しないで回避策を見つけました。私もコントローラ/サービス/ DAOのメソッドを削除し、各UploadedFileの子に1つ作成しなければなりませんでした。これを行うためのより良い方法があるように見えます。あなたの提案をお願いします。前もって感謝します! :)

答えて

0

あなたの問題は、休止状態よりも春に近いようです。この:それは、着信要求を変換する際

@ModelAttribute(value="FORM") UploadedFile form 

春は、あなたがそれをUploadedFileDocumentFile instaeadを作成することを、知る方法はありません。独自の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{ 
... 
} 
+0

ええ、それは私がやったことです。私は私の更新メッセージにそれを掲載しました。ちょうどそれをやっているよりクリーンな方法があることを望んでいた。あなたの提案に感謝します。 :) –

+0

"着信要求を変換するときに、春にはというインスタントを作成する必要があることを知る方法はありません。このステートメントは、フォームに「子」オブジェクトを送信し、フォームフィールドを設定するためにリフレクションが使用されているため、フレームワークが「子」オブジェクトを返すためにフレームワークが理解しているか、「覚えている」コントローラーのそれぞれのPOSTメソッド。 – Rick

+0

@Rickそして、私はあなたがSpring MVCに失望してしまうのではないかと心配しています。これはASPやJSFと異なり、複雑なビューステートを維持せず、ビューはモデルと疎結合しています。あなたがそのレベルの「知性」を探しているのであれば、春はあなたのために適切ではありません。一方で、より複雑で緊密に結合されたフレームワークは、代わりに他の多くの方法であなたの手を結びつけているので、常にトレードオフがあります。 – pap

関連する問題