@Nightmare058

Почему не присваивается связь many to many?

Добрый день.
Пытался разобраться, но что-то не сдюжил)
Хочу сделать REST API, чтобы запрос на логин оправлялся не через форму, а JSONом с фронта
При попытке появляется ошибка
user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));


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


57 строка UserService
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();
    }
}


UserService
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:/";
    }
}


Что отправляю из Postman

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


Ссылка на гит:
https://github.com/Akella058/notes_api
Опирался на эту статью:
https://habr.com/ru/post/482552/
Ради интереса попробовал сделать все по статье и отправить то же самое из постмана
результат тот же
  • Вопрос задан
  • 214 просмотров
Решения вопроса 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Добрый день.
Проблема вот, тут:

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 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;
    }


Подробнее про ManyToMany
https://vladmihalcea.com/the-best-way-to-use-the-m...

У вас даже в idea подсвечивается потенциальная проблема
61937f32c8b2f268382727.png
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы