N:N 연관관계 mappedBy 쪽 데이타가 안보일때
- N:N 관계에서 연관관계 주인쪽은 하위 데이타가 보이는데,
- 반대편은 LAZY 로 인해 값이 안보인다.
- 이때 보이게 하려면 DTO를 사용해서 하위 데이터를 읽어야 한다.
@Service
public class SubjectServiceImpl implements SubjectService {
@Autowired
SubjectRepository subjectRepository;
@Override
public List<SubjectDTO> findAll() {
return subjectRepository.findAll().stream()
.map(this::convertToDTO)
.collect((Collectors.toList()));
}
@Override
public List<SubjectDTO> findBySubjectNameContainsIgnoreCase(String subjectName) {
return subjectRepository.findBySubjectNameContainsIgnoreCase(subjectName, Sort.by(Sort.Direction.ASC, "subjectName")).stream()
.map(this::convertToDTO)
.collect((Collectors.toList()));
}
private SubjectDTO convertToDTO(Subject subject) {
SubjectDTO dto = new SubjectDTO();
dto.setId(subject.getId());
dto.setSubjectName(subject.getSubjectName());
dto.setMaxScore(subject.getMaxScore());
List<StudentDTO> students = subject.getStudents().stream()
.map(student -> {
StudentDTO studentDTO = new StudentDTO();
studentDTO.setId(student.getId());
studentDTO.setStudentName(student.getStudentName());
studentDTO.setCellPhone(student.getCellPhone());
return studentDTO;
})
.collect(Collectors.toList());
dto.setStudents(students);
return dto;
}
}
- StudentServiceImpl.java
- student가 연관관계 주인일때, 연관관계 주인쪽은 그냥 읽으면 하위 데이타가 읽혀진다.
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
StudentRepository studentRepository;
@Override
public List<Student> findAll() {
return studentRepository.findAll();
}
@Override
public List<Student> findByStudentNameContainsIgnoreCase(String studentName) {
return studentRepository.findByStudentNameContainsIgnoreCase(studentName, Sort.by(Sort.Direction.ASC, "studentName"));
}
}
@Entity
@Data
@Table
public class Subject implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "subject_id")
Long id;
String subjectName;
int maxScore;
@ManyToMany(mappedBy = "subjects", fetch = FetchType.EAGER)
@JsonBackReference
private List<Student> students = new ArrayList<>();
@Override
public String toString() {
return "id=" + id + ", subjectName=" + subjectName + ", maxScore=" + maxScore;
}
}
@Entity
@Data
@Table
public class Student implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "student_id")
Long id;
String studentName;
String cellPhone;
@ManyToMany (fetch = FetchType.LAZY)
@JsonManagedReference
@JoinTable(name="student_subject",
joinColumns = @JoinColumn(name="student_id"),
inverseJoinColumns = @JoinColumn(name = "subject_id"))
private List<Subject> subjects = new ArrayList<>();
@Override
public String toString() {
return "id=" + id + ", studentName=" + studentName + ", cellPhone=" + cellPhone;
}
}
public interface SubjectRepository extends JpaRepository<Subject, Long> {
@Query("SELECT s FROM Subject s JOIN FETCH s.students WHERE UPPER(s.subjectName) LIKE UPPER(CONCAT('%', :subjectName, '%'))")
List<Subject> findBySubjectNameContainsIgnoreCase(@Param("subjectName") String subjectName, Sort sort);
}
public interface StudentRepository extends JpaRepository<Student, Long> {
@Query("SELECT s FROM Student s JOIN FETCH s.subjects WHERE UPPER(s.studentName) LIKE UPPER(CONCAT('%', :studentName, '%'))")
List<Student> findByStudentNameContainsIgnoreCase(@Param("studentName") String studentName, Sort sort);
}