메인 부분에서는 전문가 답변이 나오는데

커뮤니티 detail에서는 userRole 부분이 화면에 나타나지 않음.

그렇다는 말은 머스테치에서 구현이 안된다?
{{#comm.commsByCategory.일반고민}}
<div class="c-card">
<div class="c-card-body detail">
<a href="/comm-detail/{{id}}">
<h4 class="card-title mb-10">{{this.title}}</h4>
<div class="community-cartegory">
<div class="category main-color">{{this.category}}</div>
<div class="user-info">
<figure><img src="{{comm.clientImage}}" alt="회원이미지"></figure>
<span>{{comm.name}}</span>
</div>
</div>
<p class="card-text mb-20">{{this.content}}</p>
</a>
<div class="link-wrapper">
<a href="#" class="card-link like">❤<em class="count">1</em></a>
<a href="#" class="card-link reply">💌<em class="count">2</em></a>
</div>
{{#userRole}}
<div class="expert-reply">
<div class="expert-reply-info mb-10">
<figure><img src="/images/user.png" alt="전문가 이미지가 들어갈 자리"></figure>
<span class="expert-reply-name active-color">{{expertName}}님의 전문답변</span>
</div>
<p class="reply-content">
{{solution}}
</p>
</div>
{{/userRole}}
</div>
</div>
{{/comm.commsByCategory.일반고민}}
</div>
아마 userRole이라는 속성은 main에서 구현이 된 것인데 detail에서 쓰려고 하니까 인식을 못함.
⇒ 서비스, 컨트롤러로 가서 속성을 받는 것을 땡겨와야 한다! 리스트를 들고 온 것처럼!
코드를 보면
package com.example.aboutme.comm;
import com.example.aboutme.comm.enums.CommCategory;
import com.example.aboutme.user.UserResponse;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
public interface CommRepository extends JpaRepository<Comm, Integer> {
List<Comm> findByCategory(CommCategory category);
// 메인 커뮤니티 리스트
@Query("""
SELECT new com.example.aboutme.user.UserResponse$ClientMainDTO$CommDTO(
c.id,
c.title,
c.content,
c.category,
c.user.profileImage,
c.user.name,
r.user.profileImage,
r.user.name
)
FROM Comm c
JOIN c.replies r
WHERE r.user.userRole = com.example.aboutme.user.enums.UserRole.EXPERT
""")
List<UserResponse.ClientMainDTO.CommDTO> findCommsWithReply();
// /comm 출력하려고 뽑은 쿼리
@Query("""
SELECT new com.example.aboutme.comm.CommResponse$CommAndReplyDTO(
c.id,
c.title,
c.content,
c.category,
c.user.profileImage,
c.user.name,
r.user.userRole,
r.user.profileImage,
r.user.name,
r.solution
)
FROM Comm c
JOIN c.replies r
""")
List<CommResponse.CommAndReplyDTO> findAllCommsWithReply();
}
이게 무엇인 ⇒ 한방쿼리
무슨 말인지 모르겟음…
그리고 남의 쿼리를 바꾸는 것은 위험..
⇒ 나의 dto를 새로 만들자. 형태가 비슷하면, 주용님 것을 참고로.(told by leader)
⇒ 코드 리셋하고 나의 dto를 다시 만들자.
코드를 계속 보다보니, 누가 누구 것인지 불분명,,, gpt를 이용한 것은 기억에 거의 남지 않음… 그렇다보니, 코드가 중간부터 꼬여서 점점 멀리가는 느낌이다.
하다가 꼬이고 하다가 꼬임…
⇒팀원들의 답변)
- 조인) comm entity와 reply(solution) entity를 조인을 하면 됨.
- ⇒ 그래서 reply의 solution을 가져오면 된다고 함.
코드들을 봐도 감이 잘 안옴.. 하나 하나 살펴보자
우선 뷰를 나타내는 머스태치를 보면 아래가 보이지 않음


⇒ 서비스, 레파지토리를 보자,
CommService
@RequiredArgsConstructor
@Service
public class CommService {
private final CommRepository commRepository;
//주용
public List<CommResponse.CommAndReplyDTO> findAllCommsWithReply() {
return commRepository.findAllCommsWithReply();
}
//상세페이지----------------------------------------------------------------------------
@Transactional
public CommResponse.CommDetailDTO getCommDetail(int id) {
//id로 커뮤니티를 불러올거야
Comm comm = commRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Comm not found with id " + id));
//카테고리별로 조회한 정보를 list로 게시판 들고와서 저장 / 어떤 값들이 있는지 출력
List<Comm> comms = commRepository.findByCategory(comm.getCategory());
System.out.println("comms = " + comms);
//username, client이미지,댓글내용 들고 올거야.
String userName = comm.getUser().getName();
String clientImage = comm.getUser().getProfileImage();
List<String> replyContents = comm.getReplies().stream()
.map(Reply::getContent)
.collect(Collectors.toList());
//카테고리별 댓글을 가공해서 가져올거야.
Map<String, List<CommResponse.CommDTO>> commsByCategory = comms.stream()
.collect(Collectors.groupingBy(
c -> c.getCategory().getKorean(),
Collectors.mapping(c -> new CommResponse.CommDTO(c.getId(), c.getContent(), c.getTitle(), c.getCategory().getKorean(), c.getCreatedAt()), Collectors.toList())
));
//commdetailDTO로 반환
return new CommResponse.CommDetailDTO(
comm.getId(),
clientImage,
userName,
comm.getContent(),
comm.getTitle(),
comm.getCategory().getKorean(),
comm.getCreatedAt(),
replyContents,
commsByCategory
);
}
=> 카테고리별로 댓글을 가져오는 코드---------------------------------------------------------
//id로 게시판을 가져올거야 없으면 null을 반환할거야
public Comm findById(Integer id) {
Optional<Comm> commOptional = commRepository.findById(id);
return commOptional.orElse(null); // orElse(null)을 사용하여 엔티티가 없을 경우 null 반환
}
}
CommRepository
public interface CommRepository extends JpaRepository<Comm, Integer> {
//카테고리별로 정보를 가져올거야.(jpa기능으로 메서드 이름을 통해 자동으로 쿼리가 생성됨)
List<Comm> findByCategory(CommCategory category);
// 메인 커뮤니티 리스트
@Query("""
SELECT new com.example.aboutme.user.UserResponse$ClientMainDTO$CommDTO(
c.id,
c.title,
c.content,
c.category,
c.user.profileImage,
c.user.name,
r.user.profileImage,
r.user.name
) // comm 글과 댓글의 필요한 필드를 가져온다.
FROM Comm c JOIN c.replies r // comm과 reply 엔티티 조인한다.
WHERE r.user.userRole = com.example.aboutme.user.enums.UserRole.EXPERT
""") // 근데 expert의 역할일때만 가져올거야.
List<UserResponse.ClientMainDTO.CommDTO> findCommsWithReply();
//전문가의 댓글이 달린 커뮤니티 글을 조회하여,
그 결과를 특정 형식의 객체로 반환하는 역할을 합니다.
// /comm 출력하려고 뽑은 쿼리_주용-------------------------------------------
...
CommResponse
?) 여기서
List<UserResponse.ClientMainDTO.CommDTO> 여기서 clientmaindto는 어디에 있지??
?) commdto는 너무 작은 양의 내용만 들고 있는데?_레파지토리와 일치하지 않음.
@Data //
public static class CommDTO {
private Integer id;
private String content;
private String title;
private String category;
private Timestamp createdAt;
public CommDTO(Integer id, String content, String title, String category, Timestamp createdAt) {
this.id = id;
this.content = content;
this.title = title;
this.category = category;
this.createdAt = createdAt;
}
}
@Data // 내가 짠 거_세부정보dto
public static class CommDetailDTO {
private Integer id; // comm_id
private String clientImage;
private String name;
private String content;
private String title;
private String category;
private Timestamp createdAt;
private List<String> replyContents;
private Map<String, List<CommDTO>> commsByCategory; // 카테고리별로 그룹화된 'CommDTO'객체들의 맵
public CommDetailDTO(Integer id, String clientImage, String name, String content, String title, String category, Timestamp createdAt, List<String> replyContents, Map<String, List<CommDTO>> commsByCategory) {
this.id = id;
this.clientImage = clientImage; -??? 애는 어디서 온거지? reply, user,comm 어디에도 없음
this.name = name; // user_name
this.content = content; //comm_content
this.title = title; // comm_title
this.category = category; // comm_category
this.createdAt = createdAt; // comm_created
this.replyContents = replyContents; // reply_content
this.commsByCategory = commsByCategory;
}
}
@Data // 카테고리별로 나뉠 간략한 정보를 담기 위한 dto
public static class CommDTO {
private Integer id; //comm_id
private String content; //comm_content
private String title; //comm_title
private String category; // comm_category
private Timestamp createdAt; //comm_createdAt
public CommDTO(Integer id, String content, String title, String category, Timestamp createdAt) {
this.id = id;
this.content = content;
this.title = title;
this.category = category;
this.createdAt = createdAt;
}
}
화면을 보고 dto을 그려보자

⇒
커뮤니티 상세보기 DTO
-commId
-comm_category
-comm_title
-user(client) image
-comm_createdAt
-comm_content


같은 카테고리 다른 글 dto
if) 같은 category
-commId
-comm_category
-comm_title
-User_profileImage(client) image
-comm_createdAt
-comm_content
if) userRole = expert
-userRole
-User_profileImage(expertImage)
-expertname
-expertReply
커뮤니티 상세보기
-commId
-comm_category
-comm_title
-User_profileImage(client) image
-comm_createdAt
-comm_content
-comm_name
그러면 위의 것과 합쳐보면,
-commId
-comm_category
-comm_title
-User_userRole
-User_profileImage(client) image
-comm_createdAt
-comm_content
-comm_name
if) 같은 category
if) userRole = expert
-userRole
-User_profileImage(expertImage)
-expertname
-expertReply
이것을 토대로 짜면
@Data // 내가 짠 것
public static class CommDetailDTO {
private Integer commId; // comm_id
private String commCategory; // comm_category
private String commTitle; // comm_title
private UserRole userRole; // User_userRole
private String clientProfileImage; // User_profileImage(client)
private Timestamp commCreatedAt; // comm_createdAt
private String commContent; // comm_content
private String commName; // comm_name
private List<String> replyContents; // reply list를 받아서 리스트 안에, content, user
private Map<String, List<CommDTO>> commsByCategory; // 카테고리별로 그룹화된 'CommDTO' 객체들의 맵
public CommDetailDTO(Integer commId, String commCategory, String commTitle, UserRole userRole, String clientProfileImage, Timestamp commCreatedAt, String commContent, String commName, List<String> replyContents, Map<String, List<CommDTO>> commsByCategory) {
this.commId = commId;
this.commCategory = commCategory;
this.commTitle = commTitle;
this.userRole = userRole;
this.clientProfileImage = clientProfileImage;
this.commCreatedAt = commCreatedAt;
this.commContent = commContent;
this.commName = commName;
this.replyContents = replyContents;
this.commsByCategory = commsByCategory;
}
}
@Data // 카테고리별로 나뉠 간략한 정보를 담기 위한 dto
public static class CommDTO {
private UserRole userRole;
private String expertProfileImage; // User_profileImage(expertImage)
private String category;
private String expertName; // expertname
private String expertReply; // expertReply
private Timestamp createdAt;
public CommDTO(UserRole userRole, String expertProfileImage, String category, String expertName,
}
⇒ 서비스 부분이 오류가 난다.

이 부분을 string 으로 바꾸라고
그렇지만 우리는 timestamp형식을 지켜야 한다.
그래서 이 형식을 지키고 string으로 변환시키는 코드를 짠다.

오류가 더욱 많아진다.
2시도
h2로 먼저 값을 확인한 후 필요한 값들을 체크해본다.
이상한 점 -이사이 성별 : other로 되어잇음. -게시글에 대한 전문인 댓글 내용이 solution ok


Share article