@Saintka

Почему вылетает ошибка при ленивой инициализации при работе с БД?

Если убрать @Trasactional(timeout = 2), то в консоль падает ошибка, о том что сессия закрыта, вариант с featch = FeatchType.EAGER не подходит. Возможно ли как-то избавиться от данного костыля? Я прочитал про Hibernate.initialize() но не понял в какой момент его нужно применить.

Получаю ошибку:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.SchoolJournal.SpringHibernate.model.ClassRoom.teacher, could not initialize proxy - no Session


Использую данный тест для проверки данных:
@SpringBootTest 
    @TestInstance(TestInstance.Lifecycle.PER_CLASS) 
    class SpringHibernateApplicationTests { 
    
    @Autowired 
    private PupilRepository pupilRepository; 
    
    @Autowired 
    private ClassRoomRepository classRoomRepository; 
    
    @Autowired 
    private TeacherRepository teacherRepository; 
    
    @BeforeAll 
    @Rollback(value = false) 
    public void contextLoads() { 
    Pupil pupil = new Pupil(); 
    pupil.setName("Anton"); 
    pupil.setSurname("Savridov"); 
    
    Pupil pupil1 = new Pupil(); 
    pupil1.setName("Elena"); 
    pupil1.setSurname("Antonova"); 
    
    Teacher teacher = new Teacher(); 
    teacher.setName("Alla"); 
    teacher.setSurname("Aronova"); 
    teacher.setDiscipline("Mathematics"); 
    
    ClassRoom classRoom = new ClassRoom(); 
    classRoom.setName("1A"); 
    
    pupil.setClassRoom(classRoom); 
    pupil1.setClassRoom(classRoom); 
    teacher.setClassRoom(classRoom); 
    
    classRoomRepository.save(classRoom); 
    teacherRepository.save(teacher); 
    pupilRepository.save(pupil); 
    pupilRepository.save(pupil1); 
    
    } 
    
    @Test 
    @Transaction(timeout = 2)
    public void createEntity() { 
    System.out.println("Класс"); 
    System.out.println("----------------------------"); 
    Iterable<ClassRoom> allClassRoom = classRoomRepository.findAll();
    allClassRoom.forEach(c -> System.out.println(c.getId() + " " + c.getName())); 
    allClassRoom.forEach(c -> c.getTeacher().forEach(t -> System.out.println(t.getId() + " " + t.getName() + " " + t.getSurname() + " " + t.getDiscipline()))); 
    allClassRoom.forEach(c -> c.getPupil().forEach(p -> System.out.println(p.getId() + " " + p.getName() + " " + p.getSurname()))); 
    System.out.println("----------------------------"); 
    }
  • Вопрос задан
  • 232 просмотра
Пригласить эксперта
Ответы на вопрос 1
azerphoenix
@azerphoenix Куратор тега Java
Java Software Engineer
Добрый день!
Если не ошибаюсь, то вы столкнулись с этой проблемой:
https://www.baeldung.com/spring-open-session-in-view

Говоря проще, если у вас включен open-session-in-view, то вам не нужно использовать аннотацию Transactional, но при этом это является антипаттерном

Because OSIV creates a Session at the beginning of the request, the transactional proxy uses the current available Session instead of creating a brand new one.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы