I have a bit of a problem. So I'm trying to make a form validation. I enter incorrect data and it doesn't show any problems and saves user even it should not do that. If I don't select any country, it crashes becouse it gets null. Binding result method .getAllErrors() shows nothing. The question is why binding result doesn't get any errors and validating all the fields even if they are incorrect? What I'm missing?
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.4.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.0.Final</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.4.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml</groupId>
<artifactId>classmate</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
@Entity
@Table(name="users")
public class User {
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "country_id", referencedColumnName = "id")
@NotBlank(message = "Country is mandatory")
@NotNull
private Country country;
@Column(name = "password")
@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&-+=()])(?=\\\\S+$).{8,20}$",
message = "At least one digit, upper and lower case letters at least once, special character, 8 to 20 characters and no white spaces")
@NotBlank(message = "Password is mandatory")
private String password;
@Column(name = "first_name")
@Size(min = 2, max= 20, message = "Not less then 2")
@NotBlank(message = "First name is mandatory")
private String firstName;
@Column(name = "last_name")
@Size(min = 2, max= 20, message = "Not less then 2")
@NotBlank(message = "Last name is mandatory")
private String lastName;
@Column(name = "mail")
@Email(message = "Enter valid email")
@NotBlank(message = "Email is mandatory")
private String mail;
@Column(name = "phone")
@Pattern(regexp = "^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]\\d{3}[\\s.-]\\d{4}$",
message = "Enter valid phone like:\n123-456-7890\n(123) 456-7890\n123 456 7890\n123.456.7890\n+91 (123) 456-7890")
@NotBlank(message = "Phone is mandatory")
private String phone;
@Column(name = "last_login_date")
private String lastLoginDate;
@Column(name = "register_date")
private String registerDate;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(
name = "user_roles",
joinColumns = @JoinColumn(name = "users_id"),
inverseJoinColumns = @JoinColumn(name = "roles_id")
)
@NotNull
private Set<Roles> roles = new HashSet<>();
@Controller
public class LoginController {
@Autowired
private UserService userService;
@Autowired
CountryRepository countryRepo;
@Autowired
UserRepository userRepo;
@GetMapping("/login")
public String openLogin(Model theModel) {
User user = new User();
List<Country> countryList = new ArrayList<Country>();
countryList = countryRepo.findAll();
theModel.addAttribute("user", user);
theModel.addAttribute("country_list", countryList);
return "login";
}
@PostMapping("/register")
public String registerUser(@Valid @ModelAttribute User user,
HttpServletRequest request, BindingResult result) {
if(result.hasErrors()) {
return "login";
} else {
String userRole = request.getParameter("role_value");
String selectedCountry= request.getParameter("country_value");
userService.setUserCountry(selectedCountry);
userService.setUserRole(userRole);
userService.saveUserWithRole(user);
return "redirect:/";
}
}
}
@Service
public class UserService {
private String userCountry;
private String userRole;
@Autowired
private UserRepository userRepo;
@Autowired
private RoleRepository roleRepo;
@Autowired
private CountryRepository countryRepo;
public void saveUserWithRole(User user) {
Country userCountry = countryRepo.findById(getUserCountry(this.userCountry));
user.addCountry(userCountry);
Roles userRole = roleRepo.findUsingId(getUserRole(this.userRole));
user.addRole(userRole);
userRepo.save(user);
}
public void setUserCountry(String userCountry) {
this.userCountry = userCountry;
}
public Long getUserCountry(String userCountry) {
return Long.parseLong(userCountry);
}
public void setUserRole(String userRole) {
this.userRole = userRole;
}
public Long getUserRole(String userRole) {
return Long.parseLong(userRole);
}
}
<form th:action="@{/register}" th:object="${user}" id="register-form-user"
method="post" style="display: none">
<input type="text" id="firstName" th:field="*{firstName}" name="firstName" th:errorclass="is-invalid" placeholder="Your name">
<span th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}">Error</span>
<input type="text" id="last-name" th:field="*{lastName}" name="last-name" th:errorclass="is-invalid" placeholder="Your last name">
<span th:if="${#fields.hasErrors('lastName')}" th:errors="*{lastName}">Error</span>
<input type="password" id="password" th:field="*{password}" name="password" th:errorclass="is-invalid" placeholder="Password">
<span th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Error</span>
<input type="password" id="rep-password" name="rep-password" placeholder="Repeat password">
<input type="text" id="mail" th:field="*{mail}" name="mail" th:errorclass="is-invalid" placeholder="Mail">
<span th:if="${#fields.hasErrors('mail')}" th:errors="*{mail}">Error</span>
<input type="text" id="phone" th:field="*{phone}" name="phone" th:errorclass="is-invalid" placeholder="Phone">
<span th:if="${#fields.hasErrors('phone')}" th:errors="*{phone}">Error</span>
<select class="form-control" name="role_value" id="role-name">
<option th:value="0">Select role</option>
<!-- Role options -->
</select>
<span th:if="${#fields.hasErrors('roles')}" th:errors="*{roles}">Error</span>
<select class="form-control" name="country_value" id="country-name">
<option value="0">Select country</option>
<option th:each="country : ${country_list}" th:value="${country.id}" th:text="${country.countryName}"></option>
</select>
<span th:if="${#fields.hasErrors('country')}" th:errors="*{country}">Error</span>
<button class="btn-form">REGISTER</button>
</form>
Thanks for help.