org.firebirdsql.jdbc.FBSQLExceptionInfo: validation error for column "USERS"."CPF", value "*** null ***"

350 views Asked by At

I'm getting a null value even filling the field and passing the correct parameters, but something is not coming out right, look at this login page image filled in correctly https://uploaddeimagens.com.br/imagens/P6b20Tg

SpringSecurity

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@EnableWebSecurity
public class SpringSecurity {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public static PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests((authorize)-> authorize
                        .antMatchers("/register/**").permitAll()
                        .antMatchers("/index").permitAll()
                        .antMatchers("/users").hasRole("ADMIN")
                        .anyRequest().authenticated()
                        .and()
                ).formLogin(
                        form -> form
                                .loginPage("/login")
                                .loginProcessingUrl("/login")
                                .defaultSuccessUrl("/users")
                                .permitAll()
                ).logout(
                        logout -> logout
                                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                                .permitAll()
                );
        return http.build();
    }



    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
    }
}

AuthController

package com.xxxxxxxxxxxxxxxxxxxxxxxxxx.controller;

import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.dto.UserDto;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.entity.User;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

import javax.validation.Valid;
import java.util.List;

@Controller

public class AuthController {

    private UserService userService;

    public AuthController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("index")
    public String home(){
        return "index";
    }

    @GetMapping("/login")
    public String loginForm() {
        return "login";
    }

    // método handler para lidar com a solicitação de registro do usuário
    @GetMapping("register")
    public String showRegistrationForm(Model model){
        UserDto user = new UserDto();
        model.addAttribute("user", user);
        return "register";
    }

    // método manipulador para lidar com a solicitação de envio do formulário de registro do usuário
    @PostMapping("/register/save")
    public String registration(@Valid @ModelAttribute("user") UserDto user,
                               BindingResult result,
                               Model model){
        User existing = userService.findByEmail(user.getEmail());
        if (existing != null) {
            result.rejectValue("email", null, "Já existe uma conta cadastrada com esse e-mail");
        }
        if (result.hasErrors()) {
            model.addAttribute("user", user);
            return "register";
        }
        userService.saveUser(user);
        return "redirect:/register?success";
    }

    @GetMapping("/users")
    public String listRegisteredUsers(Model model){
        List<UserDto> users = userService.findAllUsers();
        model.addAttribute("users", users);
        return "users";
    }
}

UserDto

package com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.dto;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserDto
{
    private Long id;
    @NotEmpty
    private String Name;
    @NotEmpty
    private String CPF;
    @NotEmpty(message = "O CPF não deve estar vazio")
    @Email
    private String email;
    @NotEmpty(message = "A senha não deve estar vazia")
    private String password;
}

Role

package com.xxxxxxxxxxxxxxxxxxxxxxx.entity;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import java.util.List;

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name="roles")
public class Role
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable=false, unique=true)
    private String name;

    @ManyToMany(mappedBy="roles")
    private List<User> users;
}

User

package com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.entity;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name="users")
public class User
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "Nome" ,nullable=false)
    private String name;

    @Column(nullable = false)
    private String CPF;

    @Column(nullable=false, unique=true)
    private String email;

    @Column(nullable=false)
    private String password;

    @ManyToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinTable(
            name="users_roles",
            joinColumns={@JoinColumn(name="USER_ID", referencedColumnName="ID")},
            inverseJoinColumns={@JoinColumn(name="ROLE_ID", referencedColumnName="ID")})
    private List<Role> roles = new ArrayList<>();

}

RoleRepository

package com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.repository;


import com.xxxxxxxxxxxxxxxxxxxxxxxxx.entity.Role;
import org.springframework.data.jpa.repository.JpaRepository;

public interface RoleRepository extends JpaRepository<Role, Long> {

    Role findByName(String name);
}

UserRepository

package com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.repository;


import com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

    User findByEmail(String email);

}

CustomUserDetailsService

package com.xxxxxxxxxxxxxxxxxxxxxxxxxxxx.service;

import com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.entity.Role;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.entity.User;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.repository.UserRepository;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.stream.Collectors;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private UserRepository userRepository;

    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        User user = userRepository.findByEmail(email);

        if (user != null) {
            return new org.springframework.security.core.userdetails.User(user.getEmail(),
                    user.getPassword(),
                    mapRolesToAuthorities(user.getRoles()));
        }else{
            throw new UsernameNotFoundException("Invalid username or password.");
        }
    }

    private Collection < ? extends GrantedAuthority> mapRolesToAuthorities(Collection <Role> roles) {
        Collection < ? extends GrantedAuthority> mapRoles = roles.stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList());
        return mapRoles;
    }
}

UserServiceImpl

package com.xxxxxxxxxxxxxxxxxxxxxxxxxx.service.impl;



import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.dto.UserDto;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.entity.Role;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.entity.User;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.repository.RoleRepository;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.repository.UserRepository;
import com.xxxxxxxxxxxxxxxxxxxxxxxxxx.service.UserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private UserRepository userRepository;
    private RoleRepository roleRepository;
    private PasswordEncoder passwordEncoder;

    public UserServiceImpl(UserRepository userRepository,
                           RoleRepository roleRepository,
                           PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public void saveUser(UserDto userDto) {
        User user = new User();
        user.setName(userDto.getName() + " " + userDto.getCPF());
        user.setEmail(userDto.getEmail());
        // criptografar a senha usando o spring security
        user.setPassword(passwordEncoder.encode(userDto.getPassword()));

        Role role = roleRepository.findByName("ROLE_ADMIN");
        if(role == null){
            role = checkRoleExist();
        }
        user.setRoles(Arrays.asList(role));
        userRepository.save(user);
    }

    @Override
    public User findUserByEmail(String email) {
        return userRepository.findByEmail(email);
    }

    @Override
    public User findByEmail(String email) {
        return null;
    }

    @Override
    public List<UserDto> findAllUsers() {
        List<User> users = userRepository.findAll();
        return users.stream()
                .map((user) -> mapToUserDto(user))
                .collect(Collectors.toList());
    }

    private UserDto mapToUserDto(User user){
        UserDto userDto = new UserDto();
        String[] str = user.getName().split(" ");
        userDto.setName(str[0]);
        userDto.setCPF(str[1]);
        userDto.setEmail(user.getEmail());
        return userDto;
    }

    private Role checkRoleExist(){
        Role role = new Role();
        role.setName("ROLE_ADMIN");
        return roleRepository.save(role);
    }
}

register.html

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org"
>
<head>
    <meta charset="UTF-8">
    <title>Registration and Login System</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
          rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
          crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand" th:href="@{/index}">Registration and Login System</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                <li class="nav-item">
                    <a class="nav-link active" aria-current="page" th:href="@{/login}">Login</a>
                </li>
            </ul>
        </div>
    </div>
</nav>
<br /><br /><br />
<div class="container">
    <div class="row col-md-8 offset-md-2">
        <div class="card">
            <div class="card-header">
                <h2 class="text-center">Registration</h2>
            </div>
            <div th:if="${param.success}">
                <div class="alert alert-info">
                    You have successfully registered our app!
                </div>
            </div>
            <div class="card-body">
                <form
                        method="post"
                        role="form"
                        th:action="@{/register/save}"
                        th:object="${user}"
                >
                    <div class="form-group mb-3">
                        <label class="form-label">First Name</label>
                        <input
                                class="form-control"
                                id="Name"
                                name="Name"
                                placeholder="Enter first name"
                                th:field="*{Name}"
                                type="text"
                        />
                        <p th:errors = "*{Name}" class="text-danger"
                           th:if="${#fields.hasErrors('Name')}"></p>
                    </div>

                    <div class="form-group mb-3">
                        <label class="form-label">CPF</label>
                        <input
                                class="form-control"
                                id="CPF"
                                name="CPF"
                                placeholder="CPF"
                                th:field="*{CPF}"
                                type="text"
                        />
                        <p th:errors = "*{CPF}" class="text-danger"
                           th:if="${#fields.hasErrors('CPF')}"></p>
                    </div>

                    <div class="form-group mb-3">
                        <label class="form-label">Email</label>
                        <input
                                class="form-control"
                                id="email"
                                name="email"
                                placeholder="Enter email address"
                                th:field="*{email}"
                                type="email"
                        />
                        <p th:errors = "*{email}" class="text-danger"
                           th:if="${#fields.hasErrors('email')}"></p>
                    </div>

                    <div class="form-group mb-3">
                        <label class="form-label">Password</label>
                        <input
                                class="form-control"
                                id="password"
                                name="password"
                                placeholder="Enter password"
                                th:field="*{password}"
                                type="password"
                        />
                        <p th:errors = "*{password}" class="text-danger"
                           th:if="${#fields.hasErrors('password')}"></p>
                    </div>
                    <div class="form-group">
                        <button class="btn btn-primary" type="submit">Register</button>
                        <span>Already registered? <a th:href="@{/login}">Login here</a></span>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
</body>
</html>

application.properties

spring.jpa.hibernate.ddl-auto=update
#logging.level.org.springframework=DEBUG

application.yml

spring:
  datasource:
    driver-class-name: org.firebirdsql.jdbc.FBDriver
    url: jdbc:firebirdsql:localhost/3050:C:/DB/usuarios.FDB?sql_dialect=3&charSet=utf-8
    username: SYSDBA
    password: masterkey
    hikari:
      connection-timeout: 1000
      login-timeout: 1000
      minimum-idle: 10

  jpa:
    database-platform: org.hibernate.community.dialect.FirebirdDialect
    hibernate:
      ddl-auto: validate

spom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.xxxxxxx</groupId>
    <artifactId>xxxxxxxxxxx</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>DashBoardBackend</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
        <squiggly.version>1.3.18</squiggly.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.firebirdsql.jdbc</groupId>
            <artifactId>jaybird-jdk17</artifactId>
            <version>3.0.10</version>
        </dependency>
        <dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>5.5.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-community-dialects</artifactId>
            <version>6.0.0.Alpha9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </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.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.bohnman</groupId>
            <artifactId>squiggly-filter-jackson</artifactId>
            <version>1.3.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy-agent</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Logback

2023-01-16 17:27:20.533  WARN 9548 --- [nio-8080-exec-8] o.a.c.util.SessionIdGeneratorBase        : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [154] milliseconds.
2023-01-16 17:27:38.328  WARN 9548 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 335544347, SQLState: 23000
2023-01-16 17:27:38.328 ERROR 9548 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper   : validation error for column "USERS"."CPF", value "*** null ***" [SQLState:23000, ISC error code:335544347]
2023-01-16 17:27:38.334  WARN 9548 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: 0, SQLState: null
2023-01-16 17:27:38.334  WARN 9548 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper   : Connection.isValid does not support non-zero timeouts, timeout value 5 has been ignored
2023-01-16 17:27:38.336 ERROR 9548 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause

org.firebirdsql.jdbc.FBSQLExceptionInfo: validation error for column "USERS"."CPF", value "*** null ***"
0

There are 0 answers