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!
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.