From 2aa6160a88fd3599b770033b92bfaa86694cb0b6 Mon Sep 17 00:00:00 2001 From: Ren Date: Thu, 11 May 2023 20:17:42 +0300 Subject: [PATCH 1/4] bugfix getProofKudos() in KudosService --- .../kudos/service/KudosService.java | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/provedcode/kudos/service/KudosService.java b/src/main/java/com/provedcode/kudos/service/KudosService.java index f506391..599999b 100644 --- a/src/main/java/com/provedcode/kudos/service/KudosService.java +++ b/src/main/java/com/provedcode/kudos/service/KudosService.java @@ -89,44 +89,39 @@ public KudosAmount getKudosForSponsor(long sponsorId, Authentication authenticat @Transactional(readOnly = true) public KudosAmountWithSponsor getProofKudos(long proofId, Authentication authentication) { - String login = authentication.getName(); - UserInfo userInfo = userInfoRepository.findByLogin(login) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "User with login = %s not found".formatted( - login))); - Talent talent = talentRepository.findById(userInfo.getId()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Talent with login = %s not found".formatted( - login))); - TalentProof talentProof = talentProofRepository.findById(proofId) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Proof with id = %s not found".formatted( - proofId))); + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted(login))); + Talent talent = talentRepository.findById(userInfo.getTalent().getId()) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Talent with login = %s not found".formatted(login))); + TalentProof talentProof = talentProofRepository.findById(proofId) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Proof with id = %s not found".formatted(proofId))); - Long countOfAllKudos = talentProof.getKudos().stream() - .map(Kudos::getAmount) - .reduce(0L, (prev, next) -> prev + next); + Long countOfAllKudos = talentProof.getKudos().stream() + .map(Kudos::getAmount) + .reduce(0L, (prev, next) -> prev + next); - if (talent.getId().equals(talentProof.getTalent().getId())) { - Map kudosFromSponsor = talentProof.getKudos().stream() - .collect(Collectors.toMap( - Kudos::getAmount, - proof -> proof.getSponsor() != null - ? sponsorMapper.toDto( - proof.getSponsor()) - : SponsorDTO.builder().build(), - (prev, next) -> next, - HashMap::new - )); + if (talent.getId().equals(talentProof.getTalent().getId())) { + Map kudosFromSponsor = talentProof.getKudos().stream() + .collect(Collectors.toMap( + Kudos::getAmount, + proof -> proof.getSponsor() != null + ? sponsorMapper.toDto(proof.getSponsor()) + : SponsorDTO.builder().build(), + (prev, next) -> next, + HashMap::new)); - return KudosAmountWithSponsor.builder() - .allKudosOnProof(countOfAllKudos) - .kudosFromSponsor(kudosFromSponsor) - .build(); - } else { - return KudosAmountWithSponsor.builder() - .allKudosOnProof(countOfAllKudos) - .kudosFromSponsor(null).build(); - } + return KudosAmountWithSponsor.builder() + .allKudosOnProof(countOfAllKudos) + .kudosFromSponsor(kudosFromSponsor) + .build(); + } else { + return KudosAmountWithSponsor.builder() + .allKudosOnProof(countOfAllKudos) + .kudosFromSponsor(null).build(); + } } } \ No newline at end of file From 7687e9753f8cdd4a7e248436752b1afd3e5e83fa Mon Sep 17 00:00:00 2001 From: Ren Date: Thu, 11 May 2023 21:25:03 +0300 Subject: [PATCH 2/4] Refactor schema and data to enable association of skills with proofs and talents separately Previously, tables were created to relate talent skills with talent proofs. This change separates the association of skills with talent proofs and talent. The `talent_skill` table now only links a talent with a skill, while a new `proof_skill` table relates a proof with a skill. This change also includes modifications to the `schema-V4.sql` file: adding the new `proof_skill` table, setting primary keys, and creating foreign key constraints. --- .../db/changelog/changeset/V4/data-V4.1.sql | 23 +++++++++++-------- .../db/changelog/changeset/V4/schema-V4.sql | 17 ++++++++++---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/main/resources/db/changelog/changeset/V4/data-V4.1.sql b/src/main/resources/db/changelog/changeset/V4/data-V4.1.sql index 9261f0d..b7e84e2 100644 --- a/src/main/resources/db/changelog/changeset/V4/data-V4.1.sql +++ b/src/main/resources/db/changelog/changeset/V4/data-V4.1.sql @@ -1,19 +1,22 @@ --liquibase formatted sql --changeset dennis:3 --- Skill -INSERT INTO talent_skill (proof_id, skill_id) +-- Skill in proof +INSERT INTO proof_skill (proof_id, skill_id) VALUES (1, 1); -INSERT INTO talent_skill (proof_id, skill_id) +INSERT INTO proof_skill (proof_id, skill_id) VALUES (1, 2); -INSERT INTO talent_skill (proof_id, skill_id) +INSERT INTO proof_skill (proof_id, skill_id) VALUES (1, 3); -INSERT INTO talent_skill (proof_id, skill_id) +INSERT INTO proof_skill (proof_id, skill_id) VALUES (1, 4); -INSERT INTO talent_skill (proof_id, skill_id) +INSERT INTO proof_skill (proof_id, skill_id) VALUES (4, 1); -INSERT INTO talent_skill (proof_id, skill_id) +INSERT INTO proof_skill (proof_id, skill_id) VALUES (5, 2); -INSERT INTO talent_skill (proof_id, skill_id) +INSERT INTO proof_skill (proof_id, skill_id) VALUES (6, 3); - - +-- Skill in talent +INSERT INTO talent_skill (talent_id, skill_id) +VALUES(1, 1); +INSERT INTO talent_skill (talent_id, skill_id) +VALUES(1, 2); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/V4/schema-V4.sql b/src/main/resources/db/changelog/changeset/V4/schema-V4.sql index b49be00..9355c9b 100644 --- a/src/main/resources/db/changelog/changeset/V4/schema-V4.sql +++ b/src/main/resources/db/changelog/changeset/V4/schema-V4.sql @@ -46,9 +46,14 @@ CREATE TABLE talent_proofs ( CONSTRAINT pk_talent_proofs PRIMARY KEY (id) ); CREATE TABLE talent_skill ( + talent_id BIGINT NOT NULL, + skill_id BIGINT NOT NULL, + CONSTRAINT pk_talent_skill PRIMARY KEY (talent_id, skill_id) +); +CREATE TABLE proof_skill ( proof_id BIGINT NOT NULL, skill_id BIGINT NOT NULL, - CONSTRAINT pk_talent_skill PRIMARY KEY (proof_id, skill_id) + CONSTRAINT pk_proof_skill PRIMARY KEY (proof_id, skill_id) ); CREATE TABLE skill ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -70,7 +75,7 @@ CREATE TABLE authority ( CONSTRAINT pk_authority PRIMARY KEY (id) ); CREATE TABLE user_authorities ( - authority_id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + authority_id BIGINT NOT NULL, user_id BIGINT NOT NULL, CONSTRAINT pk_user_authorities PRIMARY KEY (authority_id, user_id) ); @@ -112,9 +117,13 @@ ALTER TABLE kudos ADD CONSTRAINT FK_KUDOS_ON_PROOF FOREIGN KEY (proof_id) REFERENCES talent_proofs (id); ALTER TABLE kudos ADD CONSTRAINT FK_KUDOS_ON_SPONSOR FOREIGN KEY (sponsor_id) REFERENCES sponsor (id); +ALTER TABLE proof_skill +ADD CONSTRAINT FK_proof_skill_ON_TALENT_PROOF FOREIGN KEY (proof_id) REFERENCES talent_proofs (id); +ALTER TABLE proof_skill +ADD CONSTRAINT FK_proof_skill_ON_SKILL FOREIGN KEY (skill_id) REFERENCES skill (id); ALTER TABLE talent_skill -ADD CONSTRAINT FK_TALENT_SKILL_ON_TALENT_PROOF FOREIGN KEY (proof_id) REFERENCES talent_proofs (id); +ADD CONSTRAINT FK_talent_skill_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); ALTER TABLE talent_skill -ADD CONSTRAINT FK_TALENT_SKILL_ON_SKILL FOREIGN KEY (skill_id) REFERENCES skill (id); +ADD CONSTRAINT FK_talent_skill_ON_SKILL FOREIGN KEY (skill_id) REFERENCES skill (id); -- Indexes CREATE UNIQUE INDEX idx_login ON user_info (login) \ No newline at end of file From daea1b2cd0af0d83989cb13655d8a58f020f49f6 Mon Sep 17 00:00:00 2001 From: Ren Date: Thu, 11 May 2023 21:28:23 +0300 Subject: [PATCH 3/4] Refactor entity classes and add many-to-many relationships for talents and skills The entity classes 'Skills', 'Talent' and 'TalentProof' have been refactored to add many-to-many relationships between 'Talent' and 'Skills'. The existing 'talent_skills' table has been removed and a new table 'proof_skill' has been added to handle the many-to-many relation. --- .../talent/model/entity/Skills.java | 27 ++++++++++--- .../talent/model/entity/Talent.java | 37 +++++++++++++---- .../talent/model/entity/TalentProof.java | 40 ++++++++++++++----- 3 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/provedcode/talent/model/entity/Skills.java b/src/main/java/com/provedcode/talent/model/entity/Skills.java index 2bc6d0f..a87af65 100644 --- a/src/main/java/com/provedcode/talent/model/entity/Skills.java +++ b/src/main/java/com/provedcode/talent/model/entity/Skills.java @@ -1,11 +1,20 @@ package com.provedcode.talent.model.entity; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; + import org.hibernate.Hibernate; -import java.util.Objects; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.Setter; @Getter @Setter @@ -18,11 +27,17 @@ public class Skills { private Long id; @Column(name = "skill", length = 30) private String skill; + @ManyToMany(mappedBy = "skills") + private Set talentProofs = new LinkedHashSet<>(); + @ManyToMany(mappedBy = "skills") + private Set talents = new LinkedHashSet<>(); @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + if (this == o) + return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) + return false; Skills skills = (Skills) o; return getId() != null && Objects.equals(getId(), skills.getId()); } diff --git a/src/main/java/com/provedcode/talent/model/entity/Talent.java b/src/main/java/com/provedcode/talent/model/entity/Talent.java index 46ca5db..c093e16 100644 --- a/src/main/java/com/provedcode/talent/model/entity/Talent.java +++ b/src/main/java/com/provedcode/talent/model/entity/Talent.java @@ -1,13 +1,31 @@ package com.provedcode.talent.model.entity; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotEmpty; -import lombok.*; -import lombok.experimental.Accessors; -import org.hibernate.validator.constraints.URL; - import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; + +import org.hibernate.validator.constraints.URL; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OneToMany; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; @Builder @Accessors(chain = true) @@ -41,12 +59,15 @@ public class Talent { private TalentDescription talentDescription; @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private List talentLinks = new ArrayList<>(); -// @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) -// private List talentTalents = new ArrayList<>(); @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private List talentContacts = new ArrayList<>(); @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private List talentAttachedFiles = new ArrayList<>(); @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private List talentProofs = new ArrayList<>(); + @ManyToMany + @JoinTable(name = "talent_skills", + joinColumns = @JoinColumn(name = "talent_id"), + inverseJoinColumns = @JoinColumn(name = "skill_id")) + private Set skills = new LinkedHashSet<>(); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/model/entity/TalentProof.java b/src/main/java/com/provedcode/talent/model/entity/TalentProof.java index 549dbea..a4ffd86 100644 --- a/src/main/java/com/provedcode/talent/model/entity/TalentProof.java +++ b/src/main/java/com/provedcode/talent/model/entity/TalentProof.java @@ -1,18 +1,38 @@ package com.provedcode.talent.model.entity; +import java.time.LocalDateTime; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.hibernate.validator.constraints.URL; + import com.provedcode.kudos.model.entity.Kudos; import com.provedcode.talent.model.ProofStatus; -import jakarta.persistence.*; + +import jakarta.persistence.CascadeType; +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.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import lombok.experimental.Accessors; -import org.hibernate.validator.constraints.URL; - -import java.time.LocalDateTime; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; @Accessors(chain = true) @NoArgsConstructor @@ -44,8 +64,6 @@ public class TalentProof { @OneToMany(fetch = FetchType.EAGER, mappedBy = "proof", cascade = CascadeType.ALL, orphanRemoval = true) private List kudos; @ManyToMany - @JoinTable(name = "talent_skill", - joinColumns = @JoinColumn(name = "proof_id"), - inverseJoinColumns = @JoinColumn(name = "skill_id")) + @JoinTable(name = "proof_skill", joinColumns = @JoinColumn(name = "proof_id"), inverseJoinColumns = @JoinColumn(name = "skill_id")) private Set skills = new LinkedHashSet<>(); } \ No newline at end of file From 13a977c3019e42356db80a87066809bcac35cf34 Mon Sep 17 00:00:00 2001 From: Ren Date: Thu, 11 May 2023 21:28:57 +0300 Subject: [PATCH 4/4] Rename TalentSkillsService to ProofSkillsService and remove TalentSkills entity - Rename TalentSkillsService to ProofSkillsService for clarity - Remove TalentSkills entity which is no longer used --- .../controller/TalentSkillsController.java | 4 +-- .../talent/model/entity/TalentSkills.java | 25 ------------------- ...lsService.java => ProofSkillsService.java} | 2 +- 3 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 src/main/java/com/provedcode/talent/model/entity/TalentSkills.java rename src/main/java/com/provedcode/talent/service/{TalentSkillsService.java => ProofSkillsService.java} (99%) diff --git a/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java b/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java index bc0a57e..e477280 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentSkillsController.java @@ -2,7 +2,7 @@ import com.provedcode.talent.model.dto.ProofSkillsDTO; import com.provedcode.talent.model.dto.SkillsOnProofDTO; -import com.provedcode.talent.service.TalentSkillsService; +import com.provedcode.talent.service.ProofSkillsService; import jakarta.validation.Valid; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -18,7 +18,7 @@ @RestController @RequestMapping("/api/v4/talents") public class TalentSkillsController { - TalentSkillsService talentSkillsService; + ProofSkillsService talentSkillsService; @PostMapping("/{talent-id}/proofs/{proof-id}/skills") void addSkillOnProof(@PathVariable("talent-id") long talentId, diff --git a/src/main/java/com/provedcode/talent/model/entity/TalentSkills.java b/src/main/java/com/provedcode/talent/model/entity/TalentSkills.java deleted file mode 100644 index f6a10cc..0000000 --- a/src/main/java/com/provedcode/talent/model/entity/TalentSkills.java +++ /dev/null @@ -1,25 +0,0 @@ -//package com.provedcode.talent.model.entity; -// -//import jakarta.persistence.*; -//import jakarta.validation.constraints.NotNull; -//import lombok.*; -// -//@NoArgsConstructor -//@AllArgsConstructor -//@Builder -//@Getter -//@Setter -//@Entity -//@Table(name = "talent_talents") -//public class TalentSkills { -// @Id -// @GeneratedValue(strategy = GenerationType.IDENTITY) -// @Column(name = "id", nullable = false) -// private Long id; -// @NotNull -// @ManyToOne -// @JoinColumn(name = "talent_id", updatable = false) -// private Talent talent; -// @Column(name = "talent_name") -// private String talentName; -//} \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/TalentSkillsService.java b/src/main/java/com/provedcode/talent/service/ProofSkillsService.java similarity index 99% rename from src/main/java/com/provedcode/talent/service/TalentSkillsService.java rename to src/main/java/com/provedcode/talent/service/ProofSkillsService.java index 81841b0..84c4b2d 100644 --- a/src/main/java/com/provedcode/talent/service/TalentSkillsService.java +++ b/src/main/java/com/provedcode/talent/service/ProofSkillsService.java @@ -26,7 +26,7 @@ @Transactional @Service @AllArgsConstructor -public class TalentSkillsService { +public class ProofSkillsService { SkillsRepository skillsRepository; TalentRepository talentRepository; UserInfoRepository userInfoRepository;