-
Notifications
You must be signed in to change notification settings - Fork 0
[refactor] Post 관련 상속 전략 변경 #247
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
Changes from all commits
acbf258
16b1a5d
f7edf3a
47b5394
93c13cd
52a6a71
322ddd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,7 @@ | |
| @Entity | ||
| @Table(name = "posts") | ||
| @Getter | ||
| @Inheritance(strategy = InheritanceType.JOINED) | ||
| @Inheritance(strategy = InheritanceType.SINGLE_TABLE) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굳 |
||
| @DiscriminatorColumn(name = "dtype") | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public abstract class PostJpaEntity extends BaseJpaEntity { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.LocalDateTime; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import static com.querydsl.jpa.JPAExpressions.treat; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import static konkuk.thip.post.domain.PostType.RECORD; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import static konkuk.thip.post.domain.PostType.VOTE; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -31,8 +32,6 @@ public class RecordQueryRepositoryImpl implements RecordQueryRepository { | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final JPAQueryFactory queryFactory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final QPostJpaEntity post = QPostJpaEntity.postJpaEntity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final QRecordJpaEntity record = QRecordJpaEntity.recordJpaEntity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final QVoteJpaEntity vote = QVoteJpaEntity.voteJpaEntity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final QUserJpaEntity user = QUserJpaEntity.userJpaEntity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -47,8 +46,6 @@ public List<RoomPostQueryDto> findMyRecords(Long roomId, Long userId, Cursor cur | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| return queryFactory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .select(selectPostQueryDto()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .from(post) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .leftJoin(record).on(post.postId.eq(record.postId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .leftJoin(vote).on(post.postId.eq(vote.postId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .join(post.userJpaEntity, user) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .where(where) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .orderBy(getOrderSpecifiers(roomPostSortType)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -59,13 +56,13 @@ public List<RoomPostQueryDto> findMyRecords(Long roomId, Long userId, Cursor cur | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| private BooleanBuilder buildMyRecordCondition(Long roomId, Long userId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder where = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder voteCondition = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voteCondition.and(post.dtype.eq(VOTE.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(vote.roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder voteCondition = new BooleanBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(post.dtype.eq(VOTE.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(treat(post, QVoteJpaEntity.class).roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
-62
to
+61
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오호 이렇게 jpa treat 로 post, record, vote jpa entity 간의 명시적인 left join을 없앨 수 있군요!! 좋습니다! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder recordCondition = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recordCondition.and(post.dtype.eq(RECORD.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(record.roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder recordCondition = new BooleanBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(post.dtype.eq(RECORD.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(treat(post, QRecordJpaEntity.class).roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| where.and(voteCondition.or(recordCondition)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(post.userJpaEntity.userId.eq(userId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -84,8 +81,6 @@ public List<RoomPostQueryDto> findGroupRecordsOrderBySortType(Long roomId, Long | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| return queryFactory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .select(selectPostQueryDto()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .from(post) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .leftJoin(record).on(post.postId.eq(record.postId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .leftJoin(vote).on(post.postId.eq(vote.postId)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .join(post.userJpaEntity, user) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .where(where) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .orderBy(getOrderSpecifiers(roomPostSortType)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -96,26 +91,28 @@ public List<RoomPostQueryDto> findGroupRecordsOrderBySortType(Long roomId, Long | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| private BooleanBuilder buildRecordVoteCondition(Long roomId, Integer pageStart, Integer pageEnd, Boolean isOverview) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder where = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder voteCondition = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voteCondition.and(post.dtype.eq(VOTE.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(vote.roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // VOTE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder voteCondition = new BooleanBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(post.dtype.eq(VOTE.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(treat(post, QVoteJpaEntity.class).roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isOverview) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voteCondition.and(vote.isOverview.isTrue()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voteCondition.and(treat(post, QVoteJpaEntity.class).isOverview.isTrue()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voteCondition.and(vote.isOverview.isFalse()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(vote.page.between(pageStart, pageEnd)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| voteCondition.and(treat(post, QVoteJpaEntity.class).isOverview.isFalse()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(treat(post, QVoteJpaEntity.class).page.between(pageStart, pageEnd)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder recordCondition = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recordCondition.and(post.dtype.eq(RECORD.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(record.roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // RECORD | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder recordCondition = new BooleanBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(post.dtype.eq(RECORD.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(treat(post, QRecordJpaEntity.class).roomJpaEntity.roomId.eq(roomId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isOverview) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recordCondition.and(record.isOverview.isTrue()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recordCondition.and(treat(post, QRecordJpaEntity.class).isOverview.isTrue()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recordCondition.and(record.isOverview.isFalse()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(record.page.between(pageStart, pageEnd)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| recordCondition.and(treat(post, QRecordJpaEntity.class).isOverview.isFalse()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(treat(post, QRecordJpaEntity.class).page.between(pageStart, pageEnd)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| where.and(voteCondition.or(recordCondition)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -126,16 +123,20 @@ private BooleanBuilder buildRecordVoteCondition(Long roomId, Integer pageStart, | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Case: pageExpr (Record, Vote 분기) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private NumberExpression<Integer> pageExpr() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new CaseBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(RECORD.getType())).then(record.page) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(VOTE.getType())).then(vote.page) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(RECORD.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .then(treat(post, QRecordJpaEntity.class).page) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(VOTE.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .then(treat(post, QVoteJpaEntity.class).page) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .otherwise(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
123
to
131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pageExpr가 null을 반환할 수 있어 정렬/커서 비교가 깨집니다 — coalesce(0) 적용 권장 page가 Integer(Nullable)로 변경되었기 때문에 현재 구현은 null을 그대로 반환합니다. ORDER BY와 키셋 커서 비교(lt/eq)에서 null은 3값 논리로 처리되어 페이지네이션이 불안정해질 수 있습니다. 0으로 정규화(coalesce)해 주세요. return new CaseBuilder()
- .when(post.dtype.eq(RECORD.getType()))
- .then(treat(post, QRecordJpaEntity.class).page)
- .when(post.dtype.eq(VOTE.getType()))
- .then(treat(post, QVoteJpaEntity.class).page)
+ .when(post.dtype.eq(RECORD.getType()))
+ .then(treat(post, QRecordJpaEntity.class).page.coalesce(0))
+ .when(post.dtype.eq(VOTE.getType()))
+ .then(treat(post, QVoteJpaEntity.class).page.coalesce(0))
.otherwise(0);이 개선은 select DTO의 page 값과 Cursor.getInteger(…) 처리에서도 NPE/불일치 위험을 줄여줍니다. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Case: isOverviewExpr (총평 여부를 정렬 기준으로 사용) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private NumberExpression<Integer> isOverviewExpr() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return new CaseBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(RECORD.getType())).then(record.isOverview.castToNum(Integer.class)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(VOTE.getType())).then(vote.isOverview.castToNum(Integer.class)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(RECORD.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .then(treat(post, QRecordJpaEntity.class).isOverview.castToNum(Integer.class)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .when(post.dtype.eq(VOTE.getType())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .then(treat(post, QVoteJpaEntity.class).isOverview.castToNum(Integer.class)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .otherwise(0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
133
to
141
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isOverviewExpr도 null 가능성이 있어 비교/정렬이 불안정합니다 — coalesce(0) 적용 Boolean(Nullable) → Number로 cast한 뒤 null이 그대로 유지됩니다. eq/lt 비교와 ORDER BY에서 3값 논리로 변질되므로 0으로 coalesce 하는 편이 안전합니다. return new CaseBuilder()
- .when(post.dtype.eq(RECORD.getType()))
- .then(treat(post, QRecordJpaEntity.class).isOverview.castToNum(Integer.class))
- .when(post.dtype.eq(VOTE.getType()))
- .then(treat(post, QVoteJpaEntity.class).isOverview.castToNum(Integer.class))
+ .when(post.dtype.eq(RECORD.getType()))
+ .then(treat(post, QRecordJpaEntity.class).isOverview.castToNum(Integer.class).coalesce(0))
+ .when(post.dtype.eq(VOTE.getType()))
+ .then(treat(post, QVoteJpaEntity.class).isOverview.castToNum(Integer.class).coalesce(0))
.otherwise(0);이 변경은 selectPostQueryDto의 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.
굳굳