파이널프로젝트 -2(컨텐츠 상세페이지)

Wuchang·2023년 6월 7일
0

컨텐츠 상세페이지에 대한 데이터를 dto 로 만들어 넘기는 api 를 만들어야한다.

{
"status": "200", 
"msg": "ok",
"data": 
	{ 
		"id": 1, 
		"thumbnail" : "thumbnail.png",
		"tag1" : "시장정보",
		"tag2" : "쉽게읽혀요",
		"title" : "컨텐츠제목",
		"createdAt" : "2023-05-05",
		"pbId" : 1,
		"name" : "김피비",
		"profile" : "person.png",
		"speciality1": "US_STOCK", // 전문 분야
		"speciality2": null, // 2번이 없으면 null
		"career" : 3,
		"content" : "본문~~~"
		"reply" : [
				{ "id" : 1,
					"name" : "투자자1",
					"profile" : "person.png",
					"replyContent" : "댓글내용1",
					"createdAt" : 2023-05-05,
					"parentId" : null
				},
				{ "id" : 2,
					"name" : "투자자2",
					"profile" : "person.png",
					"replyContent" : "댓글내용2",
					"createdAt" : 2023-05-05,
					"parentId" : 1
				}
		]
	}
}

위처럼 응답하기 위해 dto 만들었고, 해당 데이터들을 받기 위한 Spring data JPA 쿼리문을 만들어야하는데, spring data jpa 에서는 List<> 타입을 parameter 로 받지 못한다고 한다.
따라서 dto 의 매개변수에서 List<'Reply> 를 빼고, Reply 들은 다른 쿼리 메서드를 통해 가져온 후 setter 이용해 dto 에 추가하는 방식으로 repository 메서드를 구성했다.
그런데 서버 실행 후 요청하니, 다음과 같은 오류가 발생했다.

{
    "status": 200,
    "msg": "ok",
    "data": {
        "id": 1,
        "thumbnail": "thumbnail.png",
        "tag1": "시장정보",
        "tag2": "쉽게읽혀요",
        "createdAt": "2023-06-07T17:18:27.905958",
        "pbId": 1,
        "name": "김pb",
        "profile": "profile.png",
        "speciality1": "BOND",
        "speciality2": null,
        "career": 10,
        "content": "content 입니다",
        "reply": [
            {
                "id": 1,
                "board": {
                    "id": 1,
                    "pb": {
                        "id": 1,
                        "branch": {
                            "id": 1
                        }
                    }
                }
            }
        ]
    }
}{
    "status": 500,
    "msg": "unknownServerError",
    "data": "Could not write JSON: could not initialize proxy [kr.co.moneybridge.model.pb.Branch#1] - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy [kr.co.moneybridge.model.pb.Branch#1] - no Session (through reference chain: kr.co.moneybridge.dto.ResponseDTO[\"data\"]->kr.co.moneybridge.dto.board.BoardResponse$BoardDetailDTO[\"reply\"]->java.util.ArrayList[0]->kr.co.moneybridge.model.board.Reply[\"board\"]->kr.co.moneybridge.model.board.Board[\"pb\"]->kr.co.moneybridge.model.pb.PB$HibernateProxy$5lPglno6[\"branch\"]->kr.co.moneybridge.model.pb.Branch$HibernateProxy$NYYWpsqe[\"company\"])"
}

알아보니, Reply 객체들이 Lazy loading 으로 가져와야하는 엔티티들과 연관관계가 맺어있는데, 조회시 이미 hibernate 세션이 닫혀있어서 발생하는 문제였다.
이를 해결하기 위해, dto 에서 List<'Reply> 가 아닌, List<'ReplyDto>로 포장했고, repository 에서 한번에 ReplyDto List 를 가져온 후 setter 통해 responseDto 에 추가해주었다.

BoardRepository

    @Query("SELECT NEW kr.co.moneybridge.dto.board.BoardResponse$BoardDetailDTO(b, pb) " +
            "FROM Board b " +
            "JOIN PB pb ON b.pb.id = pb.id " +
            "WHERE b.id = :boardId AND b.status = :status")
    BoardResponse.BoardDetailDTO findBoardWithPBReply(@Param("boardId") Long boardId, @Param("status") BoardStatus status);

ReplyRepository

    @Query("SELECT NEW kr.co.moneybridge.dto.board.BoardResponse$ReplyOutDTO(r, u) " +
            "FROM Reply r " +
            "INNER JOIN User u ON r.user.id = u.id " +
            "WHERE r.board.id = :boardId AND r.status = :status")
    List<BoardResponse.ReplyOutDTO> findRepliesByBoardId(@Param("boardId") Long boardId, @Param("status") Boolean status);
profile
우창의 개발일지🐈

0개의 댓글