I'm trying to lazily fetch a ManyToMany relationship (Courses - Students) from the Service and pass the result to the Controller. While i'm in the Service, no LazyInitializationException
is thrown, thanks to the @Transactional
annotation. However, while i'm in the Controller the LazyInitializationException
is thrown (while getting Course.students
), because the Session was closed. How can i resolve this issue, without eagerly fetch the Collection?
That's my code:
Couse Model
@Entity
@Getter
@Setter
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany
@JoinTable(name = "COURSES_STUDENTS",
joinColumns = {@JoinColumn(name = "COURSE_ID")},
inverseJoinColumns = {@JoinColumn(name = "STUDENT_ID")})
private Set<Student> students;
public Course() {
this.students = new HashSet<>();
}
Student Model
@Entity
@Getter
@Setter
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String name;
@ManyToMany(mappedBy = "students")
private Set<Course> courses;
public Student() {
this.courses = new HashSet<>();
}
}
Course Repository
@Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
}
Course Service
@Service
public class CourseService {
private final CourseRepository courseRepository;
@Autowired
public CourseService(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
@Transactional
public ResponseEntity<List<Course>> findAll() {
return this.courseRepository.findAll().isEmpty() ? ResponseEntity.noContent().build()
: ResponseEntity.ok(this.courseRepository.findAll());
}
}
Course Controller
@Controller
@RequestMapping("/")
public class CourseController {
private final CourseService courseService;
@Autowired
public CourseController(CourseService courseService) {
this.courseService = courseService;
}
@GetMapping
public ResponseEntity<List<Course>> index() {
return this.courseService.findAll();
}
}
application.properties
spring.datasource.url=jdbc:h2:~/database;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.jpa.open-in-view=false
spring.mvc.hiddenmethod.filter.enabled=true
logging.level.org.springframework.web=DEBUG
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
Thanks in advance.