-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BE] Repository 추상화 계층을 변경한다 #420
Conversation
추상화 사용하지 않는 방향으로 변경
`@SpringBootTest` 대신 `@DataJpaTest` 사용
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다~
레포 의존성이 복잡했었는데 많이 깔끔해졌네요!
코멘트 한번 확인 부탁드려요 :)
@Query("select m.id " | ||
+ "from Member m " | ||
+ "where m.platform = :platform and m.platformId = :platformId") | ||
Optional<Long> findMemberIdByPlatformAndPlatformId(@Param("platform") final Platform platform, | ||
@Param("platformId") final String platformId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CustomRepo를 만들지에 대해 논의 하는 건 어떤가요?
지금도 나쁘진 않습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반환 타입을 우리가 원하는대로 커스터마이징할 수 있다는 장점이 있겠네요.
수요일에 한 번 얘기해보죠!
@Query(value = "select distinct new com.woowacourse.naepyeon.service.dto.WrittenMessageResponseDto" | ||
+ "(m.id, r.id, r.title, t.id, t.name, m.content, m.color, " | ||
+ "case when r.recipient = com.woowacourse.naepyeon.domain.rollingpaper.Recipient.MEMBER then p.nickname " | ||
+ "when r.recipient = com.woowacourse.naepyeon.domain.rollingpaper.Recipient.TEAM then t.name " | ||
+ "else '' end) " | ||
+ "from Message m" | ||
+ ", Rollingpaper r" | ||
+ ", Team t" | ||
+ ", TeamParticipation p " | ||
+ "where m.rollingpaper.id = r.id " | ||
+ "and r.team.id = t.id " | ||
+ "and p.team.id = t.id " | ||
+ "and m.author.id = :authorId " | ||
+ "and (p.member.id = r.member.id or r.member.id is null)") | ||
Page<WrittenMessageResponseDto> findAllByAuthorId(@Param("authorId") final Long authorId, | ||
final Pageable pageRequest); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
쿼리 dsl을 활용해봐요!
그리고 세타조인이 아닌 left join과 batch size를 설정하여 Pagination을 처리할 수 있지 않을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
queryDSL은 #421 에서 해결할 예정입니다.
추가적으로 궁금한 점이 있습니다.
해당 메서드를 테스트하는 MessageRepositoryTest의 findAllByMemberIdAndPageRequest
코드에서 아래와 같은 쿼리문이 총 4번 나갑니다.
select
distinct message0_.message_id as col_0_0_,
rollingpap1_.rollingpaper_id as col_1_0_,
rollingpap1_.title as col_2_0_,
team2_.team_id as col_3_0_,
team2_.team_name as col_4_0_,
message0_.content as col_5_0_,
message0_.color as col_6_0_,
case
when rollingpap1_.classification='MEMBER' then teampartic3_.nickname
when rollingpap1_.classification='TEAM' then team2_.team_name
else ''
end as col_7_0_
from
message message0_ cross
join
rollingpaper rollingpap1_ cross
join
team team2_ cross
join
team_participation teampartic3_
where
message0_.rollingpaper_id=rollingpap1_.rollingpaper_id
and rollingpap1_.team_id=team2_.team_id
and teampartic3_.team_id=team2_.team_id
and message0_.member_id=?
and (
teampartic3_.member_id=rollingpap1_.member_id
or rollingpap1_.member_id is null
) limit ? offset ?
1번 나가는 게 맞네요. 4개 중 2개는 다른 쿼리였고, 나머지 1개는 아래 옵션때문에 동일 쿼리임에도 Hibernate와 실제쿼리용 둘 다 띄워주는 것이었네요
logging.level:
org.hibernate.SQL: debug
또 궁금한 점.
세타조인을 사용하고 있다고 생각했는데 from절 아래에 cross
라고 적혀있어서 theta join과 cross join이 같은지 궁금해서 찾아봤지만, 마땅한 답을 찾지 못했습니다. 혹시 theta join과 cross join의 차이점이 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그리고 네오한테 피드백을 받았는데 아래 쿼리처럼 null을 포함하는 쿼리는 인덱싱을 적용할 수 없다고 해서 추가적으로 회의해봐야될 것 같아요!
and (
teampartic3_.member_id=rollingpap1_.member_id
or rollingpap1_.member_id is null
) limit ? offset ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 부분은 양방향 연관을 맺고 나면 batch_size옵션으로 쿼리를 많이 단순화할 수 있을 것 같은데... TeamParticipation에 대한 양방향 매핑을 추가해서 처리하는 방법은 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 양방향도 괜찮은 것 같아요. 한번 논의해보는 게 좋겠네요
@SpringBootTest | ||
@Transactional | ||
@DataJpaTest | ||
@Import(JpaAuditingConfig.class) | ||
class MemberRepositoryTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -70,7 +75,8 @@ void createMemberWhen() { | |||
@DisplayName("회원 정보를 수정할 때 수정일자가 올바르게 나온다.") | |||
void updateMemberWhen() throws InterruptedException { | |||
final Member member = new Member("alex", "alex@naepyeon.com", Platform.KAKAO, "1"); | |||
final Long memberId = memberRepository.save(member); | |||
final Long memberId = memberRepository.save(member) | |||
.getId(); | |||
|
|||
sleep(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sleep(1);
이지금도 필요한가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
케이 수정하시느라 고생하셨습니다!
테스트 속도가 점점 개선되는게 좋네요! 👍
|
||
@SpringBootTest | ||
@Transactional | ||
@DataJpaTest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DataJpaTest로 변경했으면
EntitiyManager대신 테스트용으로 만들어진 TestEntityManager를 사용해보는건 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
처음 알았네요.
테스트하는 데엔 불편함이 없겠군요. 성능상 이점이 있는진 잘 모르겠지만 DataJpaTest에서 테스트하기 용이하도록 제공하는 entitymanager 중 하나인 것 같아 도입해보도록 하겠습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -70,7 +75,8 @@ void createMemberWhen() { | |||
@DisplayName("회원 정보를 수정할 때 수정일자가 올바르게 나온다.") | |||
void updateMemberWhen() throws InterruptedException { | |||
final Member member = new Member("alex", "alex@naepyeon.com", Platform.KAKAO, "1"); | |||
final Long memberId = memberRepository.save(member); | |||
final Long memberId = memberRepository.save(member) | |||
.getId(); | |||
|
|||
sleep(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이제 더이상 sleep은 필요 없을거같네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Analysis Details2 IssuesCoverage and DuplicationsProject ID: woowacourse-teams_2022-nae-pyeon_AYKuzmWfelLz0D2BhgWj |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
변경할 부분이 많았을 텐데 수고하셨습니다!👍
close #414
close #36
구현사항
Repository
추상화 계층 제거 -> Spring Data JPA 인터페이스 상속 이용@Query
를 이용하는 방법은 update쿼리만 날리고 select 쿼리를 날리지 않기 때문에 persistent context에 남아있고 트랜잭션이 끝나지 않아 캐시에 남아있음. 따라서 Find쿼리를 쓰면 변경 전 데이터를 가져와서 테스트 차질이 생김. 참고@SpringBootTest
제거 후@DataJpaTest
사용확인요망