Search code examples
javaspringhibernatethymeleaf

Null Pointer Exceptions when Checking That The Account Doesn’t Already Exist - Spring+Thymeleaf


I am begginer in programming so I'm sorry for that question, but sitting on it for few days and still don't know. I'm making a blog and want to check that the account doesn’t already exist (checking login name) when new user is registering. When I try to register on a site (with even not existing login name in a database)- get this error:

2018-07-27 22:27:03.561 ERROR 19368 --- [nio-8084-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at com.jzych.blog_springboot.controllers.SigninController.createUserAccount(SigninController.java:78) ~[classes/:na]
    at com.jzych.blog_springboot.controllers.SigninController.registerUserAccount(SigninController.java:61) ~[classes/:na]

It looks like there is a problem with method called "registerNewUserAccount" from UserService. Perhaps it's very simple problem but i can't find it. I was trying to instantiate a UserDto (I'm using Data transfer object) and UserEntity object but compile time error occured. Can you help me find out what's wrong with this code?

There is SigninController:

@Controller
public class SigninController {

    @Autowired
    UserRepo userRepo;
    UserService service;


    @GetMapping("/register")
    public String registerForm(Model model, WebRequest request){
        UserDto accountDto = new UserDto();
        model.addAttribute("userentity", accountDto);
        return "signinPage";
    }

    @PostMapping("/register")
    public ModelAndView registerUserAccount(@ModelAttribute("userentity") @Valid UserDto accountDto,
                                            BindingResult result, WebRequest request, Errors errors){

        UserEntity registered = new UserEntity();
        if(!result.hasErrors()){
            registered = createUserAccount(accountDto, result); //java:61
        }
        if(registered == null){
            result.rejectValue("login", "message.regError");
        }
        if(result.hasErrors()){
            return  new ModelAndView("signinPage", "userentity", accountDto);
        }
        else{
            return new ModelAndView("homePage", "userentity", accountDto);
        }
    }

    private UserEntity createUserAccount(@Valid UserDto accountDto, BindingResult result) {
        UserEntity registered = null;
        try{
            registered = service.registerNewUserAccount(accountDto); //java:78
        }catch (LoginExistsException e) {
            return null;
        }
        return registered;
    }
}

UserService class

@Service
public class UserService implements IUserService {

    @Autowired
    private UserRepo userRepo;

    @Override
    public UserEntity registerNewUserAccount(UserDto accountDto)
        throws LoginExistsException
    {

        if(loginExist(accountDto.getLogin())){
            throw new LoginExistsException(
                    "There is an account with that login:" + accountDto.getLogin());
        }

        UserEntity userEntity = new UserEntity();

        userEntity.setName(accountDto.getName());
        userEntity.setLogin(accountDto.getLogin());
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        userEntity.setPassword(passwordEncoder.encode(accountDto.getPassword()));
        userEntity.setRole(accountDto.getRole());

        return userRepo.save(userEntity);
}

    private boolean loginExist(String login){
        UserEntity userEntity = userRepo.getByLogin(login);
                if(userEntity != null) {
                    return true;
                }
                return false;
    }
}

interface

public interface IUserService {
    UserEntity registerNewUserAccount(UserDto accountDto)
        throws LoginExistsException;

and my models

@Entity
@Table(name = "user")
public class UserEntity {

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

    private String name;

    private String login;

    private String password;

    private String role;

    @OneToMany//(mappedBy = "user") kaskadowość przy usuwaniu?
    private List<Post> posts = new ArrayList<>();

    public UserEntity() {
    }

    public UserEntity(String name, String login, String password, String role) {
        this.name = name;
        this.login = login;
        this.password = password;
        this.role = role;
    }
//getters, setters, toString, hashcode and equals

UserDto model

public class UserDto {

    @NotNull
    @NotEmpty
    private String name;

    @NotEmpty
    @NotNull
    private String login;

    @NotEmpty
    @NotNull
    private String password;

    private String role;

//getters, setters and toString

very primitive page in HTML with Thymeleaf to register new user

<body>
sign in
<h1>Form</h1>
<form th:action="@{/register}" th:object = "${userentity}" method="post">
<div>
    <label>name</label>
    <input th:field = "*{name}" />
    <p th:each="error:${#fields.errors('name')}"
       th:text="${error}">Validation error</p>
</div>
    <div>
    <label>login</label>
    <input type="text" th:field = "*{login}" />
    <p th:each="error:${#fields.errors('login')}"
       th:text="${error}">Validation error</p>
    </div>
<div>
    <label>password</label>
    <input type="password" th:field = "*{password}" />
    <p th:each="error:${#fields.errors('password')}"
       th:text="${error}">Validation error</p>
</div>
<div>
    <label>role</label>
    <select th:field = "*{role}">
        <option value="ROLE_USER">USER_Role</option>
        <option value="ROLE_ADMIN">ADMIN_Role</option>
    </select>
</div>
<div>
    <p><input type="submit" value = "Sign in" /></p>
</div>
</form>
</body>

Solution

  • You forgot of @Autowired UserService class

    Wrong way:

    @Autowired
    UserRepo userRepo;
    UserService service;
    

    Right way:

    @Autowired
    UserRepo userRepo;
    @Autowired
    UserService service;