From 5e97a7042c8c3424b60a20389585f147ec918768 Mon Sep 17 00:00:00 2001 From: koosco Date: Sat, 23 Nov 2024 17:39:44 +0900 Subject: [PATCH 1/5] =?UTF-8?q?fix:=20resume=20ddl=EB=AC=B8=20title=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/init.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/init.sql b/sql/init.sql index 6e6b15c..4042d95 100644 --- a/sql/init.sql +++ b/sql/init.sql @@ -47,6 +47,7 @@ CREATE TABLE interest_job CREATE TABLE resume ( resume_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + title VARCHAR(50) NOT NULL, category VARCHAR(10) NOT NULL, content VARCHAR(50) NOT NULL, start_date DATE, @@ -86,7 +87,7 @@ CREATE TABLE quest sequence INT NOT NULL, member_id BIGINT NOT NULL, goal_id BIGINT NOT NULL, - CONSTRAINT quest_member FOREIGN KEY (member_id, goal_id) REFERENCES member_goal (member_id, goal_id) + CONSTRAINT fk_quest_member_goal FOREIGN KEY (member_id, goal_id) REFERENCES member_goal (member_id, goal_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4; From a2ecd6228c2bccfeca040489d12d205c26f05567 Mon Sep 17 00:00:00 2001 From: koosco Date: Sat, 23 Nov 2024 17:40:06 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20Member=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/groom/orbit/member/dao/jpa/entity/Member.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/com/groom/orbit/member/dao/jpa/entity/Member.java b/src/main/java/com/groom/orbit/member/dao/jpa/entity/Member.java index 964092e..8480fe0 100644 --- a/src/main/java/com/groom/orbit/member/dao/jpa/entity/Member.java +++ b/src/main/java/com/groom/orbit/member/dao/jpa/entity/Member.java @@ -14,8 +14,6 @@ import org.hibernate.annotations.ColumnDefault; -import com.groom.orbit.common.exception.CommonException; -import com.groom.orbit.common.exception.ErrorCode; import com.groom.orbit.job.dao.jpa.entity.InterestJob; import com.groom.orbit.job.dao.jpa.entity.Job; import com.groom.orbit.member.app.dto.request.UpdateMemberRequestDto; @@ -79,10 +77,4 @@ public void updateMember(UpdateMemberRequestDto requestDto, String newProfileUrl this.isNotification = requestDto.isNotification(); this.isProfile = requestDto.isProfile(); } - - public void validateId(Long id) { - if (!this.id.equals(id)) { - throw new CommonException(ErrorCode.ACCESS_DENIED); - } - } } From 8b3c8022362da62a735e55d4462b4c0651927de8 Mon Sep 17 00:00:00 2001 From: koosco Date: Sat, 23 Nov 2024 17:41:06 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20MembeGoal=20-=20Quest=20OneToMany?= =?UTF-8?q?=20=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/groom/orbit/goal/dao/entity/MemberGoal.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/com/groom/orbit/goal/dao/entity/MemberGoal.java b/src/main/java/com/groom/orbit/goal/dao/entity/MemberGoal.java index d3d17da..ca8703c 100644 --- a/src/main/java/com/groom/orbit/goal/dao/entity/MemberGoal.java +++ b/src/main/java/com/groom/orbit/goal/dao/entity/MemberGoal.java @@ -1,5 +1,9 @@ package com.groom.orbit.goal.dao.entity; +import java.util.ArrayList; +import java.util.List; + +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -7,6 +11,7 @@ import jakarta.persistence.IdClass; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import org.hibernate.annotations.ColumnDefault; @@ -41,6 +46,9 @@ public class MemberGoal { @Column(nullable = false) private Boolean isComplete; + @OneToMany(mappedBy = "memberGoal", cascade = CascadeType.ALL, orphanRemoval = true) + private List quests = new ArrayList<>(); + public static MemberGoal create(Member member, Goal goal) { MemberGoal memberGoal = new MemberGoal(); memberGoal.member = member; From daf55dbc3f311a80273c9923b8888595fd061cce Mon Sep 17 00:00:00 2001 From: koosco Date: Sat, 23 Nov 2024 17:42:37 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20LocalDateType=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resume/app/dto/ResumeRequestDto.java | 8 +++++-- .../resume/app/dto/ResumeResponseDto.java | 8 +++++-- .../groom/orbit/resume/dao/entity/Resume.java | 24 +++++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/groom/orbit/resume/app/dto/ResumeRequestDto.java b/src/main/java/com/groom/orbit/resume/app/dto/ResumeRequestDto.java index 16fc221..9e45857 100644 --- a/src/main/java/com/groom/orbit/resume/app/dto/ResumeRequestDto.java +++ b/src/main/java/com/groom/orbit/resume/app/dto/ResumeRequestDto.java @@ -1,13 +1,17 @@ package com.groom.orbit.resume.app.dto; -import java.util.Date; +import java.time.LocalDate; import com.groom.orbit.member.dao.jpa.entity.Member; import com.groom.orbit.resume.dao.entity.Resume; import com.groom.orbit.resume.dao.entity.ResumeCategory; public record ResumeRequestDto( - ResumeCategory resumeCategory, String title, String content, Date startDate, Date endDate) { + ResumeCategory resumeCategory, + String title, + String content, + LocalDate startDate, + LocalDate endDate) { public Resume toResume(Member member) { return Resume.builder() diff --git a/src/main/java/com/groom/orbit/resume/app/dto/ResumeResponseDto.java b/src/main/java/com/groom/orbit/resume/app/dto/ResumeResponseDto.java index e61f506..17a9167 100644 --- a/src/main/java/com/groom/orbit/resume/app/dto/ResumeResponseDto.java +++ b/src/main/java/com/groom/orbit/resume/app/dto/ResumeResponseDto.java @@ -1,6 +1,6 @@ package com.groom.orbit.resume.app.dto; -import java.util.Date; +import java.time.LocalDate; import com.groom.orbit.resume.dao.entity.Resume; import com.groom.orbit.resume.dao.entity.ResumeCategory; @@ -9,7 +9,11 @@ @Builder public record ResumeResponseDto( - ResumeCategory resumeCategory, String title, String content, Date startDate, Date endDate) { + ResumeCategory resumeCategory, + String title, + String content, + LocalDate startDate, + LocalDate endDate) { public static ResumeResponseDto toResumeResponseDto(Resume resume) { return ResumeResponseDto.builder() diff --git a/src/main/java/com/groom/orbit/resume/dao/entity/Resume.java b/src/main/java/com/groom/orbit/resume/dao/entity/Resume.java index a17b029..ebfdc9a 100644 --- a/src/main/java/com/groom/orbit/resume/dao/entity/Resume.java +++ b/src/main/java/com/groom/orbit/resume/dao/entity/Resume.java @@ -1,8 +1,18 @@ package com.groom.orbit.resume.dao.entity; -import java.util.Date; +import java.time.LocalDate; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; import com.groom.orbit.member.dao.jpa.entity.Member; import com.groom.orbit.resume.app.dto.ResumeRequestDto; @@ -25,21 +35,21 @@ public class Resume { @Column(name = "resume_id") private Long resumeId; - @Column(name = "category") + @Column(name = "category", length = 10) @Enumerated(EnumType.STRING) private ResumeCategory resumeCategory; - @Column(name = "title") + @Column(name = "title", length = 50) private String title; - @Column(name = "content") + @Column(name = "content", length = 50) private String content; @Column(name = "start_date") - private Date startDate; + private LocalDate startDate; @Column(name = "end_date") - private Date endDate; + private LocalDate endDate; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") From d0c571ff962ebd7e09328d9654deffdad09ab2da Mon Sep 17 00:00:00 2001 From: koosco Date: Sat, 23 Nov 2024 17:43:43 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20Quest=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=EB=B3=B5=ED=95=A9=ED=82=A4=20=EC=97=B0=EA=B4=80=EA=B4=80?= =?UTF-8?q?=EA=B3=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quest가 Member와 Quest 각각을 참조하는 문제가 있었습니다. Quest가 MemberGoal을 참조하도록 수정했습니다. --- .../orbit/goal/app/MemberGoalService.java | 10 ++++------ .../goal/app/query/QuestQueryService.java | 4 ++-- .../groom/orbit/goal/dao/QuestRepository.java | 19 +++++++++++-------- .../groom/orbit/goal/dao/entity/Quest.java | 18 ++++++++---------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java b/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java index 862176f..37049ed 100644 --- a/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java +++ b/src/main/java/com/groom/orbit/goal/app/MemberGoalService.java @@ -53,12 +53,10 @@ public List findCompletedGoals(Long memberId) { List memberGoals = memberGoalRepository.findByIsComplete(memberId, true); return memberGoals.stream() .map( - memberGoal -> { - List quests = - questQueryService.findQuestsByMemberAndGoal(memberId, memberGoal.getGoalId()); - return new GetCompletedGoalResponseDto( - memberGoal.getTitle(), quests.stream().map(Quest::getTitle).toList()); - }) + memberGoal -> + new GetCompletedGoalResponseDto( + memberGoal.getTitle(), + memberGoal.getQuests().stream().map(Quest::getTitle).toList())) .toList(); } } diff --git a/src/main/java/com/groom/orbit/goal/app/query/QuestQueryService.java b/src/main/java/com/groom/orbit/goal/app/query/QuestQueryService.java index 2e61bfa..14e7b54 100644 --- a/src/main/java/com/groom/orbit/goal/app/query/QuestQueryService.java +++ b/src/main/java/com/groom/orbit/goal/app/query/QuestQueryService.java @@ -50,10 +50,10 @@ public List findByQuestIdIn(List questIds) { } public long getTotalQuestCount(Long goalId) { - return questRepository.countByGoal_GoalId(goalId); + return questRepository.countByMemberGoal_GoalId(goalId); } public long getFinishQuestCount(Long goalId) { - return questRepository.countCompletedByGoal_GoalId(goalId); + return questRepository.countCompletedByMemberGoal_GoalId(goalId); } } diff --git a/src/main/java/com/groom/orbit/goal/dao/QuestRepository.java b/src/main/java/com/groom/orbit/goal/dao/QuestRepository.java index f29fb0f..ecc9f75 100644 --- a/src/main/java/com/groom/orbit/goal/dao/QuestRepository.java +++ b/src/main/java/com/groom/orbit/goal/dao/QuestRepository.java @@ -12,23 +12,26 @@ public interface QuestRepository extends JpaRepository { @Query( "select q from Quest q" - + " join fetch q.member m" - + " join fetch q.goal g" - + " where q.member.id=:member_id and q.goal.goalId=:goal_id") + + " join fetch q.memberGoal mg" + + " where mg.memberId=:member_id and mg.goalId=:goal_id") List findByMemberIdAndGoalId( @Param("member_id") Long memberId, @Param("goal_id") Long goalId); - @Query("select count(*) from Quest q" + " join q.goal g" + " where g.goalId=:goal_id") + @Query("select count(*) from Quest q" + " join q.memberGoal mg" + " where mg.goalId=:goal_id") int getCountByGoalId(@Param("goal_id") Long goalId); List findByQuestIdIn(List ids); - long countByGoal_GoalId(Long goalId); + @Query("select count(*) from Quest q" + " join q.memberGoal mg" + " where mg.goalId=:goal_id") + long countByMemberGoal_GoalId(@Param("goal_id") Long goalId); - @Query("select count(*) from Quest q" + " where q.goal.goalId=:goal_id and q.isComplete=true") - long countCompletedByGoal_GoalId(@Param("goal_id") Long goalId); + @Query( + "select count(*) from Quest q" + + " join q.memberGoal mg" + + " where q.isComplete=true and mg.goalId=:goal_id") + long countCompletedByMemberGoal_GoalId(@Param("goal_id") Long goalId); @Query( - "SELECT q FROM Quest q WHERE MONTH(q.deadline) = :month AND q.member.id = :memberId ORDER BY q.deadline ASC") + "SELECT q FROM Quest q join fetch q.memberGoal mg WHERE MONTH(q.deadline) = :month AND mg.memberId = :memberId ORDER BY q.deadline ASC") List findAllByMonthAndMemberId(Long memberId, Integer month); } diff --git a/src/main/java/com/groom/orbit/goal/dao/entity/Quest.java b/src/main/java/com/groom/orbit/goal/dao/entity/Quest.java index 613ef71..8e2e605 100644 --- a/src/main/java/com/groom/orbit/goal/dao/entity/Quest.java +++ b/src/main/java/com/groom/orbit/goal/dao/entity/Quest.java @@ -9,6 +9,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinColumns; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; @@ -17,7 +18,6 @@ import com.groom.orbit.common.dao.entity.BaseTimeEntity; import com.groom.orbit.common.exception.CommonException; import com.groom.orbit.common.exception.ErrorCode; -import com.groom.orbit.member.dao.jpa.entity.Member; import lombok.Getter; @@ -44,19 +44,17 @@ public class Quest extends BaseTimeEntity { private Integer sequence; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id", nullable = false) - private Member member; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "goal_id", nullable = false) - private Goal goal; + @JoinColumns({ + @JoinColumn(name = "member_id", referencedColumnName = "member_id"), + @JoinColumn(name = "goal_id", referencedColumnName = "goal_id") + }) + private MemberGoal memberGoal; public static Quest create( String title, MemberGoal memberGoal, LocalDate deadline, int newSequence) { Quest quest = new Quest(); quest.title = title; - quest.member = memberGoal.getMember(); - quest.goal = memberGoal.getGoal(); + quest.memberGoal = memberGoal; quest.sequence = newSequence; quest.deadline = deadline; @@ -71,7 +69,7 @@ public void decreaseSequence() { } public void validateMember(Long memberId) { - this.member.validateId(memberId); + this.memberGoal.getMemberId().equals(memberId); } public int compareWithId(Long questId) {