let's say I have these two entities, a student and a subject in a 1:n relation, where student can have many subjects:
@Getter @Setter
@Entity
public class Student{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id_student;
private String name;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "student", cascade = CascadeType.ALL)
private List<Subject> subject;
Here goes the constructors
And subject being:
@Getter @Setter
@Entity
public class Subject{
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id_subject;
private String name_subject;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "id_student", referencedColumnName = "id_student", nullable = false)
@JsonIgnore
private Student student;
Here goes the constructors
Is there a way to fetch only my student entity without loading in a list all of the subjects he/she is taking? My controller is:
@GetMapping("/{id_student}")
public ResponseEntity<?> verUsuario(@PathVariable Long id_student){
return studentServ.getStudent(id_student);
}
And my studentServ calls the findById() method from JpaRepository.
So far the only way I could think of to achieve this was by typing the student's getters and setters(ergo removing the @Getter and @Setter annotations) and not including the subject entity in them. I wasn't able to find an answer and I can only think of using a dto for this purpose, however my idea is that I don't want to load all of the data and then selectively passing just some information, I feel like it's a waste of resources. For this purpose I'm using Springboot framework. I think my problem is that I'm not understanding very well how lazy load works at all, because it doesn't matter whether I use Lazy or eager, on postman I get the same result for both cases, so I'm not sure how to use it. Thank you in advance!
CodePudding user response:
You can use DTO projection here. Interface projection can be used to fetch fields from mapped entity (But interface projection is slower than DTO/Class based projection).
class StudentDto {
private Long idStudent;
private String name;
//parameterized constructor and setter & getter methods
}
JPA methods:
Optional<StudentDto> findStudentDtoByIdStudent();
List<StudentDto> findBy();
For more info you can refer to: https://thorben-janssen.com/spring-data-jpa-query-projections/
Difference betweern lazy and eager loading you can find in different sessions. example if you cache the few tables at the application startup and access during a service call, for Lazy loading it will fail as it not available in this new request. However you can use Entity Graph to dynamically change the required relationship to Lazy/Eager on runtime using code.