LazyInitializationException: загрузить ленивый атрибут из сеанса, отличного от исходного в Hibernate - PullRequest
4 голосов
/ 05 мая 2020

Я новичок в спящем режиме и пытаюсь изучить нетерпеливую и ленивую загрузку

Я знаю, что если сеанс спящего режима закрыт и я попытаюсь получить ленивые данные, спящий режим выдаст исключение.

Теперь я попытался загрузить основную сущность (инструктора) в первом сеансе, а затем загрузить зависимую сущность (курс) в новом отдельном сеансе :

Основной класс (тестовый класс)

public class EagerLazyDemo {
    public static void main(String[] args) {

        SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
                .addAnnotatedClass(Instructor.class)
                .addAnnotatedClass(InstructorDetail.class)
                .addAnnotatedClass(Course.class)
                .buildSessionFactory();

        Session session = factory.getCurrentSession();

        // Begin A Transaction
        session.beginTransaction();

        // Get The Instructor From DB
        Instructor theInstructor = session.get(Instructor.class, 1);

        // Commit Transaction
        session.getTransaction().commit();

        session.close();

        //------

        //new session
        session = factory.getCurrentSession();
        session.beginTransaction();

        //Get And Display Courses For The Instructor
        List<Course> courses = theInstructor.getCourses();
        printCourses(courses);

        session.getTransaction().commit();
        session.close();

    }

    private static void printCourses(List<Course> courses) {
        for (Course c : courses) {
            System.out.println(c);
        }
    }
}

но спящий режим вызывает это исключение:

Ошибка:

Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.mehdisarf.hibernate.demo.entity.Instructor.courses, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:606)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:218)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:585)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:387)
    at com.mehdisarf.hibernate.demo.EagerLazyDemo.printCourses(EagerLazyDemo.java:55)
    at com.mehdisarf.hibernate.demo.EagerLazyDemo.main(EagerLazyDemo.java:42)

он говорит:

не удалось инициализировать прокси - нет сеанса, хотя у меня есть сеанс для загрузки зависимого объекта

Это мои классы сущностей:

Класс инструктора (основная сущность)

@Entity
@Table(name = "instructor")
public class Instructor {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "instructor_detail_id")
    private InstructorDetail instructorDetail;

    @OneToMany(fetch = FetchType.LAZY,
            mappedBy = "instructor",
            cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    private List<Course> courses;

    public Instructor() {
    }

    public Instructor(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public void addCourse(Course theCourse) {
        if (courses == null) {
            courses = new ArrayList<>();
        }

        this.courses.add(theCourse);
        theCourse.setInstructor(this);
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public InstructorDetail getInstructorDetail() {
        return instructorDetail;
    }

    public void setInstructorDetail(InstructorDetail instructorDetail) {
        this.instructorDetail = instructorDetail;
    }

    public List<Course> getCourses() {
        return courses;
    }

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }

    @Override
    public String toString() {
        return id + "" + firstName + "" + lastName + "" + email + "  (Detail:" + instructorDetail+")";
    }
}

Класс курса (зависимая сущность)

@Entity
@Table(name = "course")
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "title")
    private String title;

    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinColumn(name = "instructor_id")
    private Instructor instructor;

    public Course() {
    }

    public Course(String title) {
        this.title = title;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Instructor getInstructor() {
        return instructor;
    }

    public void setInstructor(Instructor instructor) {
        this.instructor = instructor;
    }

    @Override
    public String toString() {
        return id + "|" + title + "|";
    }
}

Ответы [ 2 ]

2 голосов
/ 05 мая 2020

Ваш объект theInstructor все еще связан с предыдущим сеансом. Чтобы получить свой объект, вы должны сделать еще один вызов после открытия нового сеанса: theInstructor = session.get (Instructor.class, 1);

1 голос
/ 11 мая 2020

«theInstructor» не привязан ни к какому сеансу, пока выполняется вызов «theInstructor.getCourses ()», это приводит к исключению.

Когда объект возвращается методом get, он находится в постоянном состоянии.

Любой экземпляр, возвращаемый методом get () или load (), является постоянным Документация сеанса

При закрытии сеанса объект "theInstructor" переходит в состояние «Отсоединено».

Отсоединен - ​​отсоединенный экземпляр - это объект, который был постоянным, но его Сессия была закрыта. Документация по состояниям объекта Hibernate

Вызов session = factory.getCurrentSession(); возвращает новый объект сеанса, но объект theInstructor не присоединяется к новому сеансу. Следовательно, попытка ленивой загрузки курсов не удалась.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...