N
N
Nightmare0582021-11-16 07:52:44
Java
Nightmare058, 2021-11-16 07:52:44

Why isn't the many to many relationship assigned?

Good afternoon.
I tried to figure it out, but I didn’t succeed)
I want to make a REST API so that the login request is not sent through the form, but with JSON from the front
When I try, an error appears

user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));


2021-11-16 07:30:02.743 ERROR 6941 --- [nio-8080-exec-2] oaccC[.[.[/].[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.example.notes.service.UserService.saveUser(UserService.java:57) ~[classes/:na]


Line 57
user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));


user
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import java.util.Collection;
import java.util.Set;

@Data
@Entity
@Table(name = "t_user")
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String password;

    @ManyToMany(fetch = FetchType.EAGER)
    private Set<Role> roles;

    public User() {
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return getRoles();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}


Role
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;

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

@Data
@Entity
@Table(name = "t_role")
public class Role implements GrantedAuthority {

    @Id
    private Long id;

    private String name;

    @Transient
    @ManyToMany(mappedBy = "roles")
    private Set<User> users;

    public Role(){}

    public Role(Long id) {
        this.id = id;
    }

    public Role(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String getAuthority() {
        return getName();
    }
}


User Service
import com.example.notes.dto.UserDto;
import com.example.notes.entity.Role;
import com.example.notes.entity.User;
import com.example.notes.repository.RoleRepository;
import com.example.notes.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class UserService implements UserDetailsService {

    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }
        return user;
    }

    public User findUserById(Long id) {
        Optional<User> userFromDb = userRepository.findById(id);
        return userFromDb.orElse(new User());
    }

    public List<User> allUsers() {
        return userRepository.findAll();
    }

    public boolean saveUser(UserDto userDto) {
        User user = userRepository.findByUsername(userDto.getUsername());
        if (user != null) {
            return false;
        }

        user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));
        user.setUsername(userDto.getUsername());
        user.setPassword(bCryptPasswordEncoder.encode(userDto.getPassword()));
        userRepository.save(user);

        return true;
    }

    public boolean deleteUser (Long id) {
        if (userRepository.findById(id).isPresent()) {
            userRepository.deleteById(id);
            return true;
        }
        return false;
    }

    public List<User> usergList (Long minId) {
        return entityManager.createQuery("SELECT u FROM User u WHERE u.id > :paramId", User.class)
                .setParameter("paramId", minId).getResultList();
    }
}


RegistrationController
import com.example.notes.dto.UserDto;
import com.example.notes.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RegistrationController {

    @Autowired
    private UserService userService;

    @PostMapping("/registration")
    public String addUser(@RequestBody UserDto userDto) {

//        if (!userDto.getPassword().equals(userDto.getPasswordConfirm())) {
//            return "Password not match";
//        }
//
//        if (!userService.saveUser(userDto)) {
//            return "User already exists";
//        }

        userService.saveUser(userDto);

        return "redirect:/";
    }
}


What I send from Postman

{
"username": "username",
"password": 123123,
"passwordConfirm": 123123
}


Link to git:
https://github.com/Akella058/notes_api
Based on this article:
https://habr.com/ru/post/482552/
For the sake of interest, I tried to do everything according to the article and send the same from the postman
, the result is the same same

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Orkhan, 2021-11-16
@Nightmare058

Good afternoon.
The problem is here:

public boolean saveUser(UserDto userDto) {
        User user = userRepository.findByUsername(userDto.getUsername());
        if (user != null) {
            return false;
        }

        user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));
        user.setUsername(userDto.getUsername());
        user.setPassword(bCryptPasswordEncoder.encode(userDto.getPassword()));
        userRepository.save(user);

        return true;
    }

Try like this:
public boolean saveUser(UserDto userDto) {
        User userFromDB = userRepository.findByUsername(userDto.getUsername());
        if (userFromDB != null) {
            return false;
        }
        User user = new User();
        user.setUsername(userDto.getUsername());
        user.setPassword(bCryptPasswordEncoder.encode(userDto.getPassword()));
        user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));
        userRepository.save(user);

        return true;
    }

More about ManyToMany
https://vladmihalcea.com/the-best-way-to-use-the-m...
You even have a potential problem highlighted in idea
61937f32c8b2f268382727.png

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question