Im very new to the SpringBoot framework, currently i'm trying to create a working page for CRUD operations required for my project.The problem is in my controller BindingResult wont catch any errors when i submit a form with empty inputs.Here's my DTO class:
package com.estate.controllers;import com.estate.model.Property;import jakarta.persistence.Column;import jakarta.persistence.PrePersist;import jakarta.persistence.Temporal;import jakarta.persistence.TemporalType;import jakarta.validation.constraints.*;import java.util.Date;import org.springframework.web.multipart.MultipartFile;public class PropertyDTO { @NotEmpty(message = "The name of the property is required") private String title; @Size(min = 10, message = "The description should be at least 10 characters long") @Size(max = 2000, message = "The description can not exceed 2000 characters") private String description; @NotEmpty(message = "The price is required") @Size(min = 0) private Double price; @NotEmpty(message = "The number of bedrooms is required") @Size(min = 0) private Integer bedrooms; @NotEmpty(message = "The number of bathrooms is required") @Size(min = 1,message = "The number of bathrooms must be at least 1") private Integer bathrooms; @NotEmpty(message = "The area is required") @Size(min = 0,message = "The area must be greater than 0") private Double area; @NotEmpty(message = "The name of the city is required") private String city; @NotEmpty(message = "The address is required") private String address; @Temporal(TemporalType.TIMESTAMP) @Column(name = "created_at") private Date createdAt; @PrePersist protected void onCreate() { createdAt = new Date(); } @Column(name = "image_url") private MultipartFile imageFile;}My controller where i even doubled the if statement for errors:
package com.estate.Admin;import com.estate.controllers.PropertyDTO;import com.estate.model.Property;import com.estate.repository.PropertyRepository;import com.estate.service.PropertyService;import jakarta.validation.Valid;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;@Controller@RequestMapping("/properties")@Validatedpublic class AdminPropertyController { private final PropertyService propertyService; @Autowired private PropertyRepository repo; public AdminPropertyController(PropertyService propertyService) { this.propertyService = propertyService; } @GetMapping({"","/"}) public String showPropertyList(Model model){ List<Property> properties = repo.findAll(); model.addAttribute("properties", properties); return "propertyTemplate/index.html"; } @GetMapping("/create") public String showCreatePage(@ModelAttribute("propertyDTO") PropertyDTO propertyDTO, Model model) { model.addAttribute("propertyDTO", propertyDTO); return "propertyTemplate/createProperty"; } @PostMapping("/create") public String CreateProperty(@ModelAttribute("propertyDTO") @Valid PropertyDTO propertyDto, @Valid BindingResult result, Model model){ if(result.hasErrors()){ model.addAttribute("errors", result.getAllErrors()); return "propertyTemplate/createProperty"; } if(result.hasErrors()){ return "propertyTemplate/createProperty"; } return "redirect:/properties"; }}And my html file, i use thymeleaf for displaying errors:
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Online catalog</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"></head><body><div class ="container"><div class="row"><div class="col-md-8 mx-auto rounded border p-4 m-4"><h2 class="text-center mb-5">New Property</h2><form :form method ="POST" enctype="multipart/form-data" th:object="${propertyDTO}"><div class="row mb-3"><label class="col-sm-4 col-form-label">Name</label><div class="col-sm-8"><input class="form-control" placeholder="Введитеназвание" th:field="${propertyDTO.title}"><p th:if="${#fields.hasErrors('title')}" th:errorclass="text-danger" th:errors="${propertyDTO.title}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Description</label><div class="col-sm-8"><textarea class="form-control" placeholder="Введитеописание" th:field="${propertyDTO.description}"></textarea><p th:if="${#fields.hasErrors('description')}" th:errorclass="text-danger" th:errors="${propertyDTO.description}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Price</label><div class="col-sm-8"><input class="form-control" type="number" step="0.01" min="0" value="0" placeholder="Введитецену" th:field="${propertyDTO.price}"><p th:if="${#fields.hasErrors('price')}" th:errorclass="text-danger" th:errors="${propertyDTO.price}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Bedrooms</label><div class="col-sm-8"><input class="form-control" type="number" step="1" min="0" value="0" placeholder="Введитеколичествокомнат" th:field="${propertyDTO.bedrooms}"><p th:if="${#fields.hasErrors('bedrooms')}" th:errorclass="text-danger" th:errors="${propertyDTO.bedrooms}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Bathrooms</label><div class="col-sm-8"><input class="form-control" type="number" step="1" min="0" value="0" placeholder="Введитеколичествокомнат" th:field="${propertyDTO.bathrooms}"><p th:if="${#fields.hasErrors('bathrooms')}" th:errorclass="text-danger" th:errors="${propertyDTO.bathrooms}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Area</label><div class="col-sm-8"><input class="form-control" type="number" step="0.01" min="0" placeholder="Введитеплощадь" th:field="${propertyDTO.area}"><p th:if="${#fields.hasErrors('area')}" th:errorclass="text-danger" th:errors="${propertyDTO.area}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">City</label><div class="col-sm-8"><input class="form-control" placeholder="Введитегород" th:field="${propertyDTO.city}"><p th:if="${#fields.hasErrors('city')}" th:errorclass="text-danger" th:errors="${propertyDTO.city}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Address</label><div class="col-sm-8"><input class="form-control" placeholder="Введитеадресс" th:field="${propertyDTO.address}"><p th:if="${#fields.hasErrors('address')}" th:errorclass="text-danger" th:errors="${propertyDTO.address}"></p></div></div><div class="row mb-3"><label class="col-sm-4 col-form-label">Image</label><div class="col-sm-8"><input type="file" class="form-control" th:field="${propertyDTO.imageFile}"><p th:if="${#fields.hasErrors('imageFile')}" th:errorclass="text-danger" th:errors="${propertyDTO.imageFile}"></p></div></div><div class="row"><div class="offset-sm-4 col-sm-4 d-grid"><button type="submit" class="btn btn-primary">Submit</button></div><div class="col-sm-4 d-grid"><a class="btn btn-outline-primary" href="/properties" role="button">Cancel</a></div></div></form></div></div></div><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script></body></html>I tried changing names of the model attribute cause at first in project logs i was seing an issue with it, but now im hard stuck at this propblem.I would appreciate any pointers for the problems or incorrections beyond the validation problem.