Error while trying to upload file conversion types mismatch



I have folowing entety.

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import org.springframework.data.annotation.CreatedDate;

@Entity
@Table(name = "documents")

public class Documents {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

     @Column(name = "date_created", nullable = false, updatable = false)
        @CreatedDate
    private Date date_created;

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

     @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "type_id", nullable = false)
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Documenttypes typeid;
     @Column(name = "file")
     private String file;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Date getDate_created() {
        return date_created;
    }
    public void setDate_created(Date date_created) {
        this.date_created = date_created;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Documenttypes getTypeid() {
        return typeid;
    }
    public void setTypeid(Documenttypes typeid) {
        this.typeid = typeid;
    }
    public String getFile() {
        return file;
    }
    public void setFile(String file) {
        this.file = file;
    }


}

One of the fields called file is to upload the document. And the controller function for this is as follows:

 public ModelAndView add(@ModelAttribute("documentsForm") Documents documents,@RequestParam("file") MultipartFile file)
     {
        //upload
         if (file.isEmpty()) {
             return new ModelAndView("redirect:/document/list");
                
            }
           try {
               byte[] bytes = file.getBytes();
               Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
            documents.setFile("test");
               Files.write(path, bytes);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

         //end
         documentsService.addDocument(documents);
         return new ModelAndView("redirect:/document/list");
         
     }

But then I try to upload file and submit a form I am getting this exception Failed to convert property value of type ‘org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile’ to required type ‘java.lang.String’ for property ‘file’; nested exception is java.lang.IllegalStateException: Cannot convert value of type ‘org.springframewo

Full error is:

2021-10-15 12:44:35.029  WARN 13500 --- [nio-8888-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'documentsForm' on field 'file': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@2c2feacc]; codes [typeMismatch.documentsForm.file,typeMismatch.file,typeMismatch.java.lang.String,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [documentsForm.file,file]; arguments []; default message [file]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'file'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'file': no matching editors or conversion strategy found]]

Answer

@ModelAttribute will enable data binding from the HTTP request to @ModelAttribute instance.

It will try to bind the value from the query parameter , field name of the form data and others (see this) to the @ModelAttribute instance ‘s field provided that their names are matched.

In your case , as your controller method has a query parameter called file , it will try to bind its value to the Documents ‘s file field. As the file query parameter is in MultipartFile type but Documents is in String type , it requires conversion but there are no Converter registered for doing it.

Not sure if you really want to bind the content of the MultipartFile to the Documents ‘s file field. If not, you can simply rename either one such that they are not matched.

Otherwise, you can implement a Converter to convert MultipartFile to String :

 public class MulitpartConverter implements Converter<MultipartFile, String> {

        @Override
        public String convert(MultipartFile source) {
            try {
                return new String(source.getBytes(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new RuntimeException("Fail to convert multipart file to string", e);
            }
        }
    }

And register it :

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
            @Override
            public void addFormatters(FormatterRegistry registry) {
                registry.addConverter(new MulitpartConverter());
            }
    
    }


Source: stackoverflow