title: Cannot convert MultipartFile into Blob in Spring
body: <p>I am trying to save an uploaded file as Blob in a MySql record. I am new to Spring. When I am about to save the record after uploading a file, then when my POST method <code>updateCandidate()</code> executes, I get this exception:</p>
  
  <blockquote>
    <p>Field error in object 'candidateForm' on field 'cv': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@59c09df6]; codes [typeMismatch.candidateForm.cv,typeMismatch.cv,typeMismatch.java.sql.Blob,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [candidateForm.cv,cv]; arguments []; default message [cv]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.sql.Blob' for property 'cv'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.sql.Blob' for property 'cv': no matching editors or conversion strategy found]</p>
  </blockquote>
  
  <p>What is going wrong? How to fix?</p>
  
  <p>My entity:</p>
  
  <pre><code>import java.sql.Blob;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.GeneratedValue;
  import javax.persistence.GenerationType;
  import javax.persistence.Id;
  import javax.persistence.Lob;
  
  @Entity
  public class Candidate {
  
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  @Column(unique = true)
  private String ssn;
  private String name;
  private String surname;
  private String technology;
  private String media;
  @Lob
  private Blob cv;
  private boolean activeCV;
  
  public Long getId() {
      return id;
  }
  public void setId(Long id) {
      this.id = id;
  }
  public String getSsn() {
      return ssn;
  }
  public void setSsn(String ssn) {
      this.ssn = ssn;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  public String getSurname() {
      return surname;
  }
  public void setSurname(String surname) {
      this.surname = surname;
  }
  public String getTechnology() {
      return technology;
  }
  public void setTechnology(String technology) {
      this.technology = technology;
  }
  public String getMedia() {
      return media;
  }
  public void setMedia(String media) {
      this.media = media;
  }
  public Blob getCv() {
      return cv;
  }
  public void setCv(Blob cv) {
      this.cv = cv;
  }
  public boolean isActiveCV() {
      return activeCV;
  }
  public void setActiveCV(boolean activeCV) {
      this.activeCV = activeCV;
  }
  
  }
  </code></pre>
  
  <p>In my service:</p>
  
  <pre><code>@Autowired
  private CandidateRepository repository;
  
  ...
  
  public Optional&lt;Candidate&gt; getCandidate(Long id){
      return repository.findById(id);
  }
  
  public void addOrUpdateCandidate(Candidate candidate) {
      repository.save(candidate);
  }
  </code></pre>
  
  <p>In my controller:</p>
  
  <pre><code>@Controller
  @RequestMapping("/candidates")
  public class CandidateController {
  
  @Autowired
  private EntityManagerFactory emf;
  
  @Autowired
  private CandidateService service;
  
  ...
  
  @GetMapping("/updateCandidate/{id}")
  public String showUpdateUserForm(@PathVariable("id") Long id, Model model) {
      Candidate candidate = service.getCandidate(id).get();
      model.addAttribute("candidateForm", candidate);
      return "updateCandidateForm";
  }
  
  @PostMapping("/updateCandidate/updateCandidateResult")
  public String updateCandidate(@ModelAttribute("candidateForm") Candidate candidate, @RequestParam("cv") MultipartFile file) throws IOException {
      InputStream iStream = file.getInputStream();
      long size = file.getSize();
      Session session = emf.unwrap(Session.class);
      Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
      candidate.setCv(cv);
      service.addOrUpdateCandidate(candidate);
      return "updateCandidateResult";
  }
  }
  </code></pre>
  
  <p>My updateCandidateForm.jsp:</p>
  
  <pre><code>&lt;%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%&gt;
  &lt;%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%&gt;
  &lt;html&gt;
      &lt;body&gt;
  
          &lt;form:form method="POST" action="updateCandidateResult" modelAttribute="candidateForm" enctype="multipart/form-data"&gt;
          &lt;form:hidden path="id"/&gt;
           &lt;table&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="name"&gt;Name&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;form:input path="name"/&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="surname"&gt;Surname&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;form:input path="surname"/&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="ssn"&gt;SSN&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;form:input path="ssn"/&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="technology"&gt;Known Technology&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;form:input path="technology"/&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="media"&gt;Found us on&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;form:input path="media"/&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="cv"&gt;Select a cv&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;input type="file" name="cv" /&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;form:label path="activeCV"&gt;Active CV&lt;/form:label&gt;&lt;/td&gt;
                  &lt;td&gt;&lt;form:checkbox path="activeCV" /&gt;&lt;/td&gt;
              &lt;/tr&gt;
              &lt;tr&gt;
                  &lt;td&gt;&lt;input type="submit" value="Submit"/&gt;&lt;/td&gt;
              &lt;/tr&gt;
          &lt;/table&gt;
      &lt;/form:form&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p></p>
  
  <p>In my POM:</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;commons-fileupload&lt;/groupId&gt;
      &lt;artifactId&gt;commons-fileupload&lt;/artifactId&gt;
      &lt;version&gt;1.3.1&lt;/version&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p><strong>EDIT 1</strong> (question):
  Would there be even a way of preventing Spring from trying to convert MultipartFile to Blob at "Submit-time", triggering this operation sooner, having the POST method already manage the Candidate (with Blob field already set) object?</p>
  
  <p><strong>EDIT 2:</strong>
  as suggested by JB Nizet, I tried to use a support POJO, which has the field CV of the type MultipartFile, to store temporarily what I post via form (text fields + file field), and I don't get that exception anymore, because at "Submit-time" the populated object has the cv field of the type of the uploaded file:</p>
  
  <pre><code>import org.springframework.web.multipart.MultipartFile;
  
  public class CandidatePOJO {
  
  private Long id;
  private String ssn;
  private String name;
  private String surname;
  private String technology;
  private String media;
  private MultipartFile cv;
  private boolean activeCV;
  
  @Override
  public String toString() {
      return "CandidatePOJO [id=" + id + ", ssn=" + ssn + ", name=" + name + ", surname=" + surname + ", technology="
              + technology + ", media=" + media + ", cv=" + cv + ", activeCV=" + activeCV + "]";
  }
  public Long getId() {
      return id;
  }
  public void setId(Long id) {
      this.id = id;
  }
  public String getSsn() {
      return ssn;
  }
  public void setSsn(String ssn) {
      this.ssn = ssn;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  public String getSurname() {
      return surname;
  }
  public void setSurname(String surname) {
      this.surname = surname;
  }
  public String getTechnology() {
      return technology;
  }
  public void setTechnology(String technology) {
      this.technology = technology;
  }
  public String getMedia() {
      return media;
  }
  public void setMedia(String media) {
      this.media = media;
  }
  public MultipartFile getCv() {
      return cv;
  }
  public void setCv(MultipartFile cv) {
      this.cv = cv;
  }
  public boolean isActiveCV() {
      return activeCV;
  }
  public void setActiveCV(boolean activeCV) {
      this.activeCV = activeCV;
  }
  }
  </code></pre>
  
  <p>in controller, now my first concern is to see whether the pojo can be correctly instantiated, so my GET-POST pair is:</p>
  
  <pre><code>@GetMapping("/updateCandidate/{id}")
  public String showUpdateUserForm(@PathVariable("id") Long id, Model model) {
      CandidatePOJO candidatePOJO = new CandidatePOJO();
      candidatePOJO.setId(id);
      model.addAttribute("candidateForm", candidatePOJO);
      return "updateCandidateForm";
  }
  
  @PostMapping("/updateCandidate/updateCandidateResult")
  public String updateCandidate(@ModelAttribute("candidateForm") CandidatePOJO candidatePOJO) {
      System.out.println("CANDIDATE POJO");
      System.out.println(candidatePOJO.toString());   // here I notice id = null
  
      /* MultipartFile to Blob conversion */
      //  MultipartFile file = candidatePOJO.getCv();
      //  InputStream iStream = file.getInputStream();
      //  long size = file.getSize();
      //  Session session = emf.unwrap(Session.class);
      //  Blob cv = Hibernate.getLobCreator(session).createBlob(iStream, size);
  
      /* instantiating the entity object to be freezed in db */
      // Candidate candidate = new Candidate();
      // set all data from candidatePOJO..
      //      candidate.setCv(cv);
  
      //  service.addOrUpdateCandidate(candidate);
      return "updateCandidateResult";
  }
  </code></pre>
  
  <p>and I get a CandidatePOJO object with no id set. I don't manage to have the id pass from GET to POST. Does anyone know what is gong wrong?</p>
  
  <p><strong>EDIT 3:</strong>
  after many days I opted for the solution with a support POJO, unbelievably I am noticing that the ID is passed from the GET method to the POST one (I haven't changed anything, I have just performed the classical Maven project cleaning as I did when I posted my issue). Unluckily I am facing now another exception (after restoring the code previously commented in the POST method, of course):</p>
  
  <blockquote>
    <p>javax.persistence.PersistenceException: Hibernate cannot unwrap EntityManagerFactory as 'org.hibernate.Session'</p>
  </blockquote>
  
  <p>How to fix that?</p>
  
  <p><strong>EDIT 4:</strong>
  Exception just above solved replacing:</p>
  
  <pre><code>Session session = emf.unwrap(Session.class);
  </code></pre>
  
  <p>with:</p>
  
  <pre><code>EntityManager em = emf.createEntityManager();
  Session session = (Session) em.getDelegate();
  </code></pre>