지난글에서 ManyToMany 로 양방향 맵핑까지 해주었다.
기존 Dto 같은 경우에는 게시글에 Hashtag String으로 있기때문에, 단건으로 게시글을 작성하거나 Response 로 받아올때 String으로 받아오도록 되어있었다.
그렇기 때문에 이제는 hashtag Set을 담아오도록 수정해야한다.
그 전에 HashtagRepository 를 생성해주고, JpaRepository 를 Extends 해준 뒤에, HashtagDto 부터 만들어보자.
public record HashtagDto(Long id, String hashtag) {
public static HashtagDto of(String hashtag) {
return new HashtagDto(null, hashtag);
}
public static HashtagDto of(Long id, String hashtag) {
return new HashtagDto(id, hashtag);
}
public static HashtagDto from(Hashtag entity) {
return new HashtagDto(
entity.getId(),
entity.getHashtag()
);
}
public Hashtag toEntity() {
return Hashtag.of(
id,
hashtag
);
}
필요에 따라서 record 로 작성할 수 있고, 세터가 필요하다면 class 로 작성할 수 있다.
record 로 편하게 작성하는 쉬운 방법이 있다.
바로 유료 플러그인인 JpaBuddy 를 활용하는것이다.
유료 플러그인이지만 한달동안 무료체험이 가능하다. (나같은 경우에는 필요하다면 유료로 결제할 마음도 있을만큼 유용하다.)
이렇게 인텔리제이상에 새로만들기 탭에 강아지모양 메뉴가 새로 생긴다. 온갖 기능이 있지만 지금 내 레벨에서는 Dto생성할때 활용하기 굉장히 좋았다.
이렇게 엔티티를 설정하면 레코드 형식으로 Dto를 생성해준다.
이제 HashtagDto 까지 생성해주었으니, 게시글을 등록할때 전달해줄 RequestDto와 출력할때 필요한 Response Dto들을 수정해준다.
이경우에는 크게 수정할것들 없이 기존에 String Hashtag 이렇게 되어있는 것들을 HashtagDto 타입을 가진 HashSet 으로 변경해주면 된다.
게시글을 등록할때 사용하는 RequestDto 같은 경우에는, 여러가지 방안을 생각할 필요가 있다.
단순히 하나만 등록한다고 하면, #안녕 이런식으로 등록할 수 있지만, 복수 등록할때는 #안녕 #안녕하 #안녕하세 #안녕하세요 이렇게 입력을 했을때 4개의 해시태그를 등록할 수 있도록 설계하면 좋을것이다.
그래서 RequestDto 같은 경우에는 세터를 사용할 수 있게 레코드 형식이 아닌 클래스로 작성을 해줌으로써, String Hashtag 를 입력받아오고, StringTokenizer 로 '#' 별로 토큰을 생성해 HashtagDto.of(st.nextToken()) 을 활용했고, replaceAll 로 공백을 제거해준뒤에 입력시켜주었다.
해시태그 같은 경우에는 따로 해시태그를 사용하는 곳이 대부분 게시글에서 사용된다고 생각했기때문에, 따로 hashtagService 를 만들어주지 않고 ArticleService 에 hashtag 관련 로직들을 설계해주었다.
이 경우에는 사실 ManyToMany 로 임시 중간 테이블이 생성되는 상태이기 때문에 , 단순히 따로 HashtagService 를 생성해서 해시태그를 저장해줄 필요 없이 이미 맵핑이 되어있는 상태이기 때문에, 게시글만 저장해도 자동으로 hashtag까지 저장이 된다.
이렇게 순서대로 따라하다 보면, 오류가 생긴다.
바로 중간 임시 테이블 (게시글이 post고 태그가 tag 면 post_tag 라는 테이블이 자동으로 생성될 것이다.) 이 각각 연결관계마다 고유 id를 갖고있지 않기때문에 오류가 발생할것이다.
대표적으로 한 게시물에 해시태그를 두개이상 등록하려 시도했을때 오류가 발생할 것이고, 설계 자체가 잘못되었다고 생각하면 될것같다. (글쓴이가 어디서 글보고 이게 잘못된 설계라고 생각하고 온게 아니라 글쓴이가 직접 시행착오 겪어보니 구조 자체가 이상했었다..)
해시태그의 본질은 내가 여러 해시태그를 등록했을때 그 해시태그가 등록된 게시물을 조회할 수 있어야하는데 복수 등록에 오류가 발생한는게 가장 컸고
그 다음으로 중간관계 맵핑이 엔티티가 아닌 ManyToMany 임시테이블이다 보니, 게시글을 삭제할때 해시태그도 같이 삭제된다는게 크다.
거기에 ManyToMany 관계를 맺어주는것은 실무에서 사용하기엔 한계가 있다는 글을 자주 보았다.
Spring-boot JPA @ManyToMany 실무에서 사용하면 안되는 이유
바로 위의 이유와 비슷한것같다. 세밀하게 테이블을 다룰 방법이 없기 때문에, ManyToMany를 없애고 중간 엔티티를 따로 만들어줘서 맵핑을 관리하도록 하는 방향으로 선택했다.
다음 글에서 알아보자.