Error: no matching editors or conversion strategy found

Mình đang làm 1 trang thêm 1 lớp học’
Domain

@Entity
@Table
@Data
public class Classes implements Serializable{
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	@Column(length = 50)
	@NotNull
	private String name;
	
	@OneToMany(mappedBy = "classes", cascade = CascadeType.ALL)
	private Set<Info> infoStudents;
}

DTO

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ClassDto implements Serializable {
	private Integer id;
	private String name;

	private Boolean isEdit;
}

Controller

@GetMapping("add")
	public String addOrEdit(ModelMap model, Classes classes,ClassDto dto) {
		dto.setIsEdit(false);
		model.addAttribute("classes", dto);
		return "admin/class/addOrEdit";
	}

	@PostMapping("saveOrUpdate")
	public ModelAndView saveOrUpdate(ModelMap model,@Valid @ModelAttribute("classes")ClassDto classDto
			, Classes entity,BindingResult result) {
		if(result.hasErrors())return new ModelAndView("/admin/class/addOrEdit");
		BeanUtils.copyProperties(classDto, entity);
		classService.save(entity);
		model.addAttribute("message", "Save Success!");
		return new ModelAndView("redirect:/admin/class/");
	}

HTML

<form th:action="@{/admin/class/saveOrUpdate}" method="post" th:object="${classes}" enctype="multipart/form-data">
		<h2 th:text="${classes.isEdit ? 'Edit Class' : 'Add New Class'}">Add New Class</h2>
		<input type="hidden" th:field="*{isEdit}">
		<div th:if="${classes.IsEdit}">
			<label class="form-label">Id</label>
			<input type="text" class="form-control" aria-describedby="classIdHid" placeholder="Id" th:field="*{id}" readonly="readonly">
			<small id="classIdHid" class="form-text text-muted">Class Id is required</small>
		</div>
		<div class="mb-3">
			
			<label class="form-label">Name</label>
			<input type="text" class="form-control" placeholder="name" th:field="*{name}" aria-describedby="classNameHid">
			<small id="classNameHid" class="form-text text-muted">Class Name is required</small>
		</div>
		<div class="mb-3">
			<button class="btn btn-primary" th:text="${classes.isEdit ? 'Update' : 'Save'}">Save</button>
			<button><a th:href="@{/admin/class/	}">Back</a></button> 
		</div>
	</form>

và khi nhập dữ liệu nó báo lỗi

Resolved [org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes': no matching editors or conversion strategy found]

Cậu ném tớ cái stacktrace được không? :smile: Ý tớ là exception trên được tung ra ở dòng nào vậy cậu?

4 Likes

Trong TH cậu không biết, khi 1 exception được tung ra, cậu sẽ có thể đọc thông tin vị trí lỗi từ stacktrace của exception đó.
Thường thì nó sẽ ở trong log của cậu (hoặc stdout nếu cậu config log in hết ra đó).
Sẽ rất hữu ích nếu cậu bắt đầu từ đó, đọc stacktrace để biết vị trí lỗi. Từ đó, cậu sẽ có thêm manh mối thôi :smile:

Hope it helps!

2 Likes

Mình thường xem lỗi khi nó hiện ở web or trên console nên không biết làm sao để mở log đó. Bạn có thể chỉ cho mình được không. Mình dùng Eclipse và Xampp

Trên eclipse có console đấy cậu. Cậu có thể xem log trên đó (tớ hi vọng cậu không có bất cứ config đặc biệt nào về log ở app của cậu).
Cậu cũng có thể check log của apache trong xampp. Google để biết thêm nơi tìm file log đó nha.

Log là tài sản quý nhất để troubleshooting, vậy nên, nếu cậu không tìm được log hoặc không đọc log, cậu không thể tìm được nguyên nhân đâu :smile:

3 Likes

Bên Console chỉ hiển thị có 1 dòng lỗi đó à

Failed to convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes': no matching editors or conversion strategy found
org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:76)
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:53)
	at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:696)
	at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:180)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:179)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:146)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
	at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'com.example.demo.model.ClassDto' to required type 'com.example.demo.domain.Classes': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:262)
	at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:73)
	... 50 more

Còn đây là bên web

  1. Tớ không thấy khai báo model attribute “classes” ở HTML template của cậu.
  2. Ở saveOrUpdate method, Classes entity không có tác dụng gì phải không? :smile:

Ở stacetrace cậu đưa, cậu có thể thấy exception được tung ra từ filter, khi nó convert dữ liệu sang POJO. Tớ thấy cậu có 1 class tên là Classes, rồi model attribute classes lại được gán cho ClassDto (tương đối confuse đó) => rất có thể đây là nguyên nhân khi spring cố tìm conversion giữa Classes và ClassDto.
Tớ nghĩ cậu cần xóa Classes entity ở method parameter đi, để nó là local variable trong method, và khai báo model attribute trong template của cậu.

Cậu thử đọc article này và làm theo nha:
https://www.baeldung.com/spring-mvc-and-the-modelattribute-annotation

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?