Here are my ProjectController:
package db.lab6.projectmanagement.controller;import db.lab6.projectmanagement.dto.MemberDto;import db.lab6.projectmanagement.dto.ProjectDto;import db.lab6.projectmanagement.entity.Member;import db.lab6.projectmanagement.entity.Project;import db.lab6.projectmanagement.service.ProjectService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;import java.util.List;import java.util.Set;@RestController@RequestMapping("/projects")public class ProjectController { private final ProjectService projectService; @Autowired public ProjectController(ProjectService projectService) { this.projectService = projectService; } @GetMapping("/{projectId}") private ResponseEntity<Project> getProject(@PathVariable Long projectId) { return ResponseEntity.ok(projectService.findById(projectId)); } @PostMapping public ResponseEntity<Project> createProject(@RequestBody ProjectDto projectDto) { return ResponseEntity.status(HttpStatus.CREATED).body(projectService.create(projectDto)); } @GetMapping("/{projectId}/members") public ResponseEntity<Set<Member>> getAllMembersFromProject(@PathVariable Long projectId) { return ResponseEntity.ok(projectService.findMembers(projectId)); } // other mappings}
Here are my ProjectService:
package db.lab6.projectmanagement.service.impl;import db.lab6.projectmanagement.dto.MemberDto;import db.lab6.projectmanagement.dto.ProjectDto;import db.lab6.projectmanagement.entity.Member;import db.lab6.projectmanagement.entity.Project;import db.lab6.projectmanagement.entity.Role;import db.lab6.projectmanagement.entity.User;import db.lab6.projectmanagement.repository.MemberRepository;import db.lab6.projectmanagement.repository.ProjectRepository;import db.lab6.projectmanagement.service.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.HashSet;import java.util.List;import java.util.Set;@Servicepublic class ProjectServiceImpl implements ProjectService { private final ProjectRepository projectRepository; private final MemberRepository memberRepository; private final UserService userService; private final RoleService roleService; @Autowired public ProjectServiceImpl(ProjectRepository projectRepository, MemberRepository memberRepository, UserService userService, RoleService roleService) { this.projectRepository = projectRepository; this.memberRepository = memberRepository; this.userService = userService; this.roleService = roleService; } @Override public Project findById(Long id) { return projectRepository.findById(id).orElseThrow(() -> new ProjectNotFoundException(id)); } @Override public Project create(ProjectDto projectDto) { User ownerUser = userService.findByNickname(projectDto.getOwnerNickname()); Role ownerRole = roleService.findByName("OWNER"); Member ownerMember = Member.builder() .user(ownerUser) .role(ownerRole).build(); Set<Member> members = new HashSet<>(); members.add(ownerMember); Project project = Project.builder() .name(projectDto.getName()) .description(projectDto.getDescription()) .members(members).build(); return projectRepository.save(project); } @Override public Set<Member> findMembers(Long id) { Project project = findById(id); return project.getMembers(); } // other methods}
Project entity:
package db.lab6.projectmanagement.entity;import com.fasterxml.jackson.annotation.JsonIgnore;import jakarta.persistence.*;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.util.HashSet;import java.util.Set;@AllArgsConstructor@NoArgsConstructor@Data@Builder@Entity@Table(name = "projects")public class Project { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String name; private String description; @OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) @JsonIgnore private Set<Task> tasks; @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) @JoinTable(name = "project_member", joinColumns = @JoinColumn(name = "project_id"), inverseJoinColumns = @JoinColumn(name = "member_id")) private Set<Member> members;}
Member enitity:
package db.lab6.projectmanagement.entity;import com.fasterxml.jackson.annotation.JsonIgnore;import jakarta.persistence.*;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import java.util.HashSet;import java.util.Set;@AllArgsConstructor@NoArgsConstructor@Data@Builder@Entity@Table(name = "members")public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "user_id", nullable = false) private User user; @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "role_id", nullable = false) private Role role; @ManyToMany(mappedBy = "members", fetch = FetchType.EAGER) @JsonIgnore private Set<Project> projects;}
When I create a project, I get a project that includes members
t.ex.
{"id": 1,"name": "foo name","description": "some description","members": [ {"id": 1,"user": {"id": 1,"email": "myemail@gmail.com","nickname": "dimitri","password": "123456" },"role": {"id": 1,"name": "OWNER" } } ]}
But when I want to get the project I recieve
{"id": 1,"name": "foo name","description": "some description","members": []}
The point is that the database contains a list of members tied to the project in project_member.
I tried to change fetch = FetchType.EAGER to FetchType.LAZY and vice versa but it didn't help. I traced sql requests and they looked good. I even ran them in the database directly and it outputted everything correctly.
Here's a trace of the sql request if needed
select p1_0.id, p1_0.description, m1_0.project_id, m1_1.id, m1_1.role_id, m1_1.user_id, p1_0.name from projects p1_0 left join project_member m1_0 on p1_0.id=m1_0.project_id left join members m1_1 on m1_1.id=m1_0.member_id where p1_0.id=?