오류해결 - 연관매핑 오류 해결

Yu Seong Kim·2024년 1월 18일
0

SpringBoot

목록 보기
14/29

jwt와 시큐리티를 이용한 게시판 REST API를 만들면서 생긴 오류입니다.

로그인 후 JWT토큰 반환

스웨거를 이용하여 로그인을 후 JWT 토큰을 받습니다.

JWT TOKEN을 이용한 게시물 작성

문제점

User 1 : Board N 으로 매핑을 하였습니다. 그러나 user: null이 나왔고,
데이터베이스를 확인

user_id가 null이 뜨는 문제점을 발견하였고, 이에 대해서 고민을 해보았습니다.
그러나 생각해보니 매핑만 하고 Service로직을 바꾸지 않은 치명적인 실수였습니다.ㅜㅜ

ServiceImpl 확인

package com.springboot.jwt_securityprac2.service.Impl;

import com.springboot.jwt_securityprac2.dto.BoardDTO.BoardRequestDto;
import com.springboot.jwt_securityprac2.dto.BoardDTO.BoardResponseDto;
import com.springboot.jwt_securityprac2.entity.Board;
import com.springboot.jwt_securityprac2.entity.User;
import com.springboot.jwt_securityprac2.jwt.JwtProvider;
import com.springboot.jwt_securityprac2.repository.BoardRepository;
import com.springboot.jwt_securityprac2.repository.UserRepository;
import com.springboot.jwt_securityprac2.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service

public class BoardServiceImpl implements BoardService {
    private Logger logger = LoggerFactory.getLogger(BoardService.class);

    private final BoardRepository boardRepository;
    private final UserRepository userRepository;

    private JwtProvider jwtProvider;

    public BoardServiceImpl(BoardRepository boardRepository,JwtProvider jwtProvider
            ,UserRepository userRepository){
        this.boardRepository = boardRepository;
        this.jwtProvider = jwtProvider;
        this.userRepository = userRepository;
    }

    @Override
    public BoardResponseDto getContent(Long id){
        logger.info("[getContent] : 게시글 반환");
        Board board = boardRepository.findById(id).get();
        BoardResponseDto boardResponseDto  = new BoardResponseDto();
        boardResponseDto.setId(board.getId());
        boardResponseDto.setContent(board.getContent());
        boardResponseDto.setTitle(board.getTitle());
        boardResponseDto.setUpdateAt(board.getCreateDate());
        boardResponseDto.setUpdateAt(board.getUpdateDate());


        return boardResponseDto;

    }
    @Override
    public BoardResponseDto saveBoard(BoardRequestDto boardRequestDto) {
        logger.info("[saveBoard] 게시글 저장 : {}",boardRequestDto.toString());


            Board board = new Board();
            board.setTitle(boardRequestDto.getTitle());
            board.setContent(boardRequestDto.getContent());
            board.setCreateDate(LocalDateTime.now());
            board.setUpdateDate(LocalDateTime.now());




        Board savedBoard = boardRepository.save(board);

            BoardResponseDto boardResponseDto = new BoardResponseDto();
            boardResponseDto.setId(savedBoard.getId());
            boardResponseDto.setTitle(savedBoard.getTitle());
            boardResponseDto.setContent(savedBoard.getContent());
            boardResponseDto.setCreateAt(LocalDateTime.now());
            boardResponseDto.setUpdateAt(LocalDateTime.now());
            boardResponseDto.setUser(savedBoard.getUser());

            return boardResponseDto;

    }

    @Override
    public BoardResponseDto changeBoard(Long id, String title, String content){
        logger.info("[changeBoard] : 게시글 수정");
        Board findBoard = boardRepository.getById(id);
        findBoard.setTitle(title);
        findBoard.setContent(content);
        findBoard.setUpdateDate(LocalDateTime.now());
        Board board = boardRepository.save(findBoard);

        BoardResponseDto boardResponseDto = new BoardResponseDto();
        boardResponseDto.setId(board.getId());
        boardResponseDto.setTitle(board.getTitle());
        boardResponseDto.setContent(board.getContent());
        boardResponseDto.setUpdateAt(LocalDateTime.now());

        return  boardResponseDto;

    }
    @Override
    public void deleteBoard(Long id){
        logger.info("[deleteBoard] : 게시글 삭제");
       boardRepository.deleteById(id);
    }
}

saveBoard()메서드를 보면 알 수 있듯이, 검증된 유저를 받아서 저장하는 로직이 비어있어서 추가 하였습니다!

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-> 현재 실행 중인 스레드의 보안 컨텍스트에서 Authentication 객체를 가져옵니다. Authentication 객체는 현재 인증된 사용자의 정보를 포함하고 있습니다. 이 객체에는 사용자의 이름, 권한, 기타 세부 정보 등이 포함될 수 있습니다.

String email = authentication.getName();
-> 여기서 authentication.getName() 메서드는 일반적으로 현재 인증된 사용자의 사용자명을 반환합니다. 스프링 시큐리티에서 사용자명은 일반적으로 사용자의 주요 식별자로 사용됩니다.
User user = userRepository.getByEmail(email);

userRepository.getByEmail(email);
-> 이 메서드는 데이터베이스에서 주어진 이메일 주소를 가진 User 엔티티를 검색합니다. 이 메서드는 userRepository 인터페이스에 정의된 메서드일 것이며, 이메일을 기반으로 사용자를 찾기 위한 쿼리를 실행합니다. 이렇게 검색된 User 객체는 게시판 엔티티에 사용자 정보를 연결하는 데 사용될 수 있습니다.

    @Override
    public BoardResponseDto saveBoard(BoardRequestDto boardRequestDto) {
        logger.info("[saveBoard] 게시글 저장 : {}",boardRequestDto.toString());

            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();  	//추가한코드
            String email = authentication.getName();		//추가한코드
            User user = userRepository.getByEmail(email);	//추가한코드

            Board board = new Board();
            board.setTitle(boardRequestDto.getTitle());
            board.setContent(boardRequestDto.getContent());
            board.setCreateDate(LocalDateTime.now());
            board.setUpdateDate(LocalDateTime.now());
            board.setUser(user);							//추가한코드




        Board savedBoard = boardRepository.save(board);

            BoardResponseDto boardResponseDto = new BoardResponseDto();
            boardResponseDto.setId(savedBoard.getId());
            boardResponseDto.setTitle(savedBoard.getTitle());
            boardResponseDto.setContent(savedBoard.getContent());
            boardResponseDto.setCreateAt(LocalDateTime.now());
            boardResponseDto.setUpdateAt(LocalDateTime.now());
            boardResponseDto.setUser(savedBoard.getUser());

            return boardResponseDto;

    }

데이터베이스를 확인해 보겠습니다!!!
업로드중..

로직을 추가하니 매핑을 하여 잘들어옵니다!!

profile
인생을 코딩하는 남자.

0개의 댓글