From b0b03dc11e85ac4aff8668056ee398dd94582cea Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 8 May 2024 17:36:53 +0900 Subject: [PATCH] =?UTF-8?q?refact:=20=EA=B7=B8=EB=A3=B9=20=EC=B4=88?= =?UTF-8?q?=EB=8C=80=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 그룹 초대 엔티티 수정 - 그룹 생성 시 그룹 초대 쿼리 추가 --- .../FriendInviteQueryRepository.java | 8 +++- .../core/domain/group/entity/GroupInvite.java | 17 ++++++- .../GroupInviteQueryRepository.java | 8 ++++ .../GroupInviteQueryRepositoryImpl.java | 48 +++++++++++++++++++ .../repository/GroupInviteRepository.java | 6 ++- .../group/service/GroupWriteServiceImpl.java | 37 ++++++++++---- .../core/domain/member/entity/Member.java | 3 -- .../db/migration/V25__group_invite_update.sql | 20 ++++++++ 8 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepository.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepositoryImpl.java create mode 100644 backend/core/src/main/resources/db/migration/V25__group_invite_update.sql diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepository.java index 640c2077d..3e6859eea 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepository.java @@ -2,7 +2,9 @@ import java.sql.PreparedStatement; import java.sql.SQLException; +import java.sql.Timestamp; import java.sql.Types; +import java.time.ZonedDateTime; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.jdbc.core.BatchPreparedStatementSetter; @@ -19,8 +21,8 @@ public void bulkSave(final Long ownerId, final List friendIds) { jdbcTemplate.batchUpdate( """ INSERT INTO friend_invite ( - friend_invite_id, owner_id, friend_id - ) values (?, ?, ?) + friend_invite_id, owner_id, friend_id, created_at, updated_at + ) values (?, ?, ?, ?, ?) """, new BatchPreparedStatementSetter() { @@ -30,6 +32,8 @@ public void setValues(final PreparedStatement ps, final int i) throws SQLExcepti ps.setNull(1, Types.BIGINT); ps.setLong(2, ownerId); ps.setLong(3, friendId); + ps.setTimestamp(4, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); + ps.setTimestamp(5, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); } @Override diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/entity/GroupInvite.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/entity/GroupInvite.java index 41c184b35..434e245ba 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/entity/GroupInvite.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/entity/GroupInvite.java @@ -27,7 +27,20 @@ public class GroupInvite extends BaseEntity { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id", nullable = false) - private Member member; + @JoinColumn(name = "group_owner_id", nullable = false) + private Member groupOwner; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_member_id", nullable = false) + private Member groupMember; + + private GroupInvite(Member groupOwner, Member groupMember) { + this.groupOwner = groupOwner; + this.groupMember = groupMember; + } + + public static GroupInvite createOf(Member groupOwner, Member groupMember) { + return new GroupInvite(groupOwner, groupMember); + } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepository.java new file mode 100644 index 000000000..e9abf2cf4 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepository.java @@ -0,0 +1,8 @@ +package site.timecapsulearchive.core.domain.group.repository; + +import java.util.List; + +public interface GroupInviteQueryRepository { + + void bulkSave(final Long groupOwnerId, final List groupMemberIds); +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepositoryImpl.java new file mode 100644 index 000000000..3fdf1ef9c --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteQueryRepositoryImpl.java @@ -0,0 +1,48 @@ +package site.timecapsulearchive.core.domain.group.repository; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; +import java.time.ZonedDateTime; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class GroupInviteQueryRepositoryImpl implements GroupInviteQueryRepository { + + private final JdbcTemplate jdbcTemplate; + + @Override + public void bulkSave(Long groupOwnerId, List groupMemberIds) { + jdbcTemplate.batchUpdate( + """ + INSERT INTO group_invite ( + group_invite_id, group_owner_id, group_member_id, created_at, updated_at + ) values (?, ?, ?, ?, ?) + """, + new BatchPreparedStatementSetter() { + + @Override + public void setValues(final PreparedStatement ps, final int i) throws SQLException { + final Long groupMember = groupMemberIds.get(i); + ps.setNull(1, Types.BIGINT); + ps.setLong(2, groupOwnerId); + ps.setLong(3, groupMember); + ps.setTimestamp(4, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); + ps.setTimestamp(5, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); + } + + @Override + public int getBatchSize() { + return groupMemberIds.size(); + } + } + ); + } + +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteRepository.java index edd27e243..585a107ca 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/repository/GroupInviteRepository.java @@ -1,9 +1,11 @@ package site.timecapsulearchive.core.domain.group.repository; -import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.Repository; import site.timecapsulearchive.core.domain.group.entity.GroupInvite; -public interface GroupInviteRepository extends JpaRepository { +public interface GroupInviteRepository extends Repository, + GroupInviteQueryRepository { + void save(GroupInvite groupInvite); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java index f714d5432..0f43f8ea0 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java @@ -9,9 +9,11 @@ import site.timecapsulearchive.core.domain.group.data.dto.GroupCreateDto; import site.timecapsulearchive.core.domain.group.data.dto.GroupOwnerSummaryDto; import site.timecapsulearchive.core.domain.group.entity.Group; +import site.timecapsulearchive.core.domain.group.entity.GroupInvite; import site.timecapsulearchive.core.domain.group.entity.MemberGroup; import site.timecapsulearchive.core.domain.group.exception.GroupNotFoundException; import site.timecapsulearchive.core.domain.group.exception.GroupOwnerAuthenticateException; +import site.timecapsulearchive.core.domain.group.repository.GroupInviteRepository; import site.timecapsulearchive.core.domain.group.repository.GroupRepository; import site.timecapsulearchive.core.domain.group.repository.MemberGroupRepository; import site.timecapsulearchive.core.domain.member.entity.Member; @@ -23,9 +25,10 @@ @RequiredArgsConstructor public class GroupWriteServiceImpl implements GroupWriteService { - private final GroupRepository groupRepository; private final MemberRepository memberRepository; + private final GroupRepository groupRepository; private final MemberGroupRepository memberGroupRepository; + private final GroupInviteRepository groupInviteRepository; private final TransactionTemplate transactionTemplate; private final SocialNotificationManager socialNotificationManager; @@ -42,6 +45,7 @@ public void createGroup(final Long memberId, final GroupCreateDto dto) { protected void doInTransactionWithoutResult(TransactionStatus status) { groupRepository.save(group); memberGroupRepository.save(memberGroup); + groupInviteRepository.bulkSave(memberId, dto.targetIds()); } }); @@ -51,15 +55,32 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { @Override public void inviteGroup(final Long memberId, final Long groupId, final Long targetId) { - final GroupOwnerSummaryDto summaryDto = memberGroupRepository.findOwnerInMemberGroup( - groupId, memberId).orElseThrow(GroupNotFoundException::new); + final Member groupOwner = memberRepository.findMemberById(memberId).orElseThrow( + MemberNotFoundException::new); + + final Member groupMember = memberRepository.findMemberById(targetId).orElseThrow( + MemberNotFoundException::new); + + final GroupInvite groupInvite = GroupInvite.createOf(groupOwner, groupMember); + + final GroupOwnerSummaryDto[] summaryDto = new GroupOwnerSummaryDto[1]; + + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + summaryDto[0] = memberGroupRepository.findOwnerInMemberGroup( + groupId, memberId).orElseThrow(GroupNotFoundException::new); - if (!summaryDto.isOwner()) { - throw new GroupOwnerAuthenticateException(); - } + if (!summaryDto[0].isOwner()) { + throw new GroupOwnerAuthenticateException(); + } + + groupInviteRepository.save(groupInvite); + } + }); - socialNotificationManager.sendGroupInviteMessage(summaryDto.nickname(), - summaryDto.groupProfileUrl(), List.of(targetId)); + socialNotificationManager.sendGroupInviteMessage(summaryDto[0].nickname(), + summaryDto[0].groupProfileUrl(), List.of(targetId)); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java index 730084363..17abf213c 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member/entity/Member.java @@ -77,9 +77,6 @@ public class Member extends BaseEntity { @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private List capsules; - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List groupInvites; - @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private List groups; diff --git a/backend/core/src/main/resources/db/migration/V25__group_invite_update.sql b/backend/core/src/main/resources/db/migration/V25__group_invite_update.sql new file mode 100644 index 000000000..729e12a70 --- /dev/null +++ b/backend/core/src/main/resources/db/migration/V25__group_invite_update.sql @@ -0,0 +1,20 @@ +alter table group_invite + drop foreign key fk_group_invite_member_id; + +alter table group_invite + drop column member_id; + + +ALTER TABLE group_invite + ADD COLUMN group_owner_id BIGINT; +ALTER TABLE group_invite + ADD COLUMN group_member_id BIGINT; + +ALTER TABLE group_invite + ADD CONSTRAINT fk_group_invite_group_owner_id FOREIGN KEY (group_owner_id) REFERENCES member (member_id); + +ALTER TABLE group_invite + ADD CONSTRAINT fk_group_invite_group_member_id FOREIGN KEY (group_member_id) REFERENCES member (member_id); + +ALTER TABLE group_invite + ADD CONSTRAINT unique_owner_member_pair UNIQUE (group_owner_id, group_member_id);