Как при использовании "ленивой загрузки" (LAZY) в Hibernate обеспечить подгрузку коллекций сущностей (связь

0
12 янв 2019 12:58
Здравствуйте!

Помогите пожалуйста с кодом для подгрузки сущностей с коллекциями, которые содержат объекты для связи OneToMany.

У меня есть 2-е сущности, связанные между собой связью Один ко Многим, 1-ая сущность для этой связи содержит коллекцию объектов 2-ой сущности - "private Collection<ChildrenEntity> childrenByIdEmployee". Для подгрузки связей прописал ленивую загрузку, как советуют в интернете (указал аннотацию "@ManyToOne(fetch = FetchType.LAZY)" во 2-ой сущности). Проблема в том, что я не знаю теперь как прописать запрос на загрузку объектов сущностей из БД так, что бы подгружались и коллекции объектов. Вот как я это пытаюсь сделать:

public class EmployeeEntityService extends BuildSessionFactory {

    public List<EmployeeEntity> getAllEmploes()
    {
        Session session=openTransactionSession();
        String sqlSelect="SELECT * FROM employee";
        SQLQuery query=session.createSQLQuery(sqlSelect).addEntity(EmployeeEntity.class);
        List<EmployeeEntity> employeeList=query.list();
        closeTransactionSession();
        return employeeList;
    }
}


Но при этом варианте, когда потом я пытаюсь обратиться к коллекции мне выдаёт исключение о том, что сессии нет, что и понятно, она была закрыта при завершении метода

Quote:
Exception in thread "AWT-EventQueue-0" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: Entity.EmployeeEntity.childrenByIdEmployee, could not initialize proxy - no Session


Подскажите как мне прописать выгрузку объектов так, чтобы при "ленивой загрузки" у меня подтянулись коллекции отвечающие за связь "один ко многим"?

@Entity
@Table(name = "employee", schema = "staffdepartment", catalog = "")
public class EmployeeEntity {
    private int idEmployee;
    private String firstName;
    private String lastName;
    private String patronymicName;
    private String passwordData;
    private Date dateBirth;
    private String pol;
    private Integer inn;
    private Date dateEmployment;
    private Collection<ChildrenEntity> childrenByIdEmployee;
    private PostanddepartmentEntity postanddepartmentByIdPostAndDepartment;

    @Id
    @Column(name = "id_Employee", nullable = false)
    public int getIdEmployee() {
        return idEmployee;
    }

    public void setIdEmployee(int idEmployee) {
        this.idEmployee = idEmployee;
    }

    @Basic
    @Column(name = "FirstName", nullable = true, length = 30)
    public String getFirstName() {
        return firstName;
    }

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

    @Basic
    @Column(name = "LastName", nullable = true, length = 30)
    public String getLastName() {
        return lastName;
    }

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

    @Basic
    @Column(name = "PatronymicName", nullable = true, length = 30)
    public String getPatronymicName() {
        return patronymicName;
    }

    public void setPatronymicName(String patronymicName) {
        this.patronymicName = patronymicName;
    }

    @Basic
    @Column(name = "PasswordData", nullable = true, length = 100)
    public String getPasswordData() {
        return passwordData;
    }

    public void setPasswordData(String passwordData) {
        this.passwordData = passwordData;
    }

    @Basic
    @Column(name = "DateBirth", nullable = true)
    public Date getDateBirth() {
        return dateBirth;
    }

    public void setDateBirth(Date dateBirth) {
        this.dateBirth = dateBirth;
    }

    @Basic
    @Column(name = "Pol", nullable = true, length = 3)
    public String getPol() {
        return pol;
    }

    public void setPol(String pol) {
        this.pol = pol;
    }

    @Basic
    @Column(name = "INN", nullable = true)
    public Integer getInn() {
        return inn;
    }

    public void setInn(Integer inn) {
        this.inn = inn;
    }

    @Basic
    @Column(name = "DateEmployment", nullable = true)
    public Date getDateEmployment() {
        return dateEmployment;
    }

    public void setDateEmployment(Date dateEmployment) {
        this.dateEmployment = dateEmployment;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        EmployeeEntity that = (EmployeeEntity) o;

        if (idEmployee != that.idEmployee) return false;
        if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;
        if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false;
        if (patronymicName != null ? !patronymicName.equals(that.patronymicName) : that.patronymicName != null)
            return false;
        if (passwordData != null ? !passwordData.equals(that.passwordData) : that.passwordData != null) return false;
        if (dateBirth != null ? !dateBirth.equals(that.dateBirth) : that.dateBirth != null) return false;
        if (pol != null ? !pol.equals(that.pol) : that.pol != null) return false;
        if (inn != null ? !inn.equals(that.inn) : that.inn != null) return false;
        if (dateEmployment != null ? !dateEmployment.equals(that.dateEmployment) : that.dateEmployment != null)
            return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = idEmployee;
        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        result = 31 * result + (patronymicName != null ? patronymicName.hashCode() : 0);
        result = 31 * result + (passwordData != null ? passwordData.hashCode() : 0);
        result = 31 * result + (dateBirth != null ? dateBirth.hashCode() : 0);
        result = 31 * result + (pol != null ? pol.hashCode() : 0);
        result = 31 * result + (inn != null ? inn.hashCode() : 0);
        result = 31 * result + (dateEmployment != null ? dateEmployment.hashCode() : 0);
        return result;
    }

    @OneToMany(mappedBy = "employeeByIdEmployee")
    public Collection<ChildrenEntity> getChildrenByIdEmployee() {
        return childrenByIdEmployee;
    }

    public void setChildrenByIdEmployee(Collection<ChildrenEntity> childrenByIdEmployee) {
        this.childrenByIdEmployee = childrenByIdEmployee;
    }

    @ManyToOne
    @JoinColumn(name = "id_PostAndDepartment", referencedColumnName = "id_PostAndDepartment")
    public PostanddepartmentEntity getPostanddepartmentByIdPostAndDepartment() {
        return postanddepartmentByIdPostAndDepartment;
    }

    public void setPostanddepartmentByIdPostAndDepartment(PostanddepartmentEntity postanddepartmentByIdPostAndDepartment) {
        this.postanddepartmentByIdPostAndDepartment = postanddepartmentByIdPostAndDepartment;
    }
}


@Entity
@Table(name = "children", schema = "staffdepartment", catalog = "")
public class ChildrenEntity {
    private int idChildren;
    private String firstName;
    private String lastName;
    private String patronymicName;
    private String pol;
    private Date dateBirth;
    @ManyToOne(fetch = FetchType.LAZY)
    private EmployeeEntity employeeByIdEmployee;

    @Id
    @Column(name = "id_Children", nullable = false)
    public int getIdChildren() {
        return idChildren;
    }

    public void setIdChildren(int idChildren) {
        this.idChildren = idChildren;
    }

    @Basic
    @Column(name = "FirstName", nullable = true, length = 30)
    public String getFirstName() {
        return firstName;
    }

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

    @Basic
    @Column(name = "LastName", nullable = true, length = 30)
    public String getLastName() {
        return lastName;
    }

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

    @Basic
    @Column(name = "PatronymicName", nullable = true, length = 30)
    public String getPatronymicName() {
        return patronymicName;
    }

    public void setPatronymicName(String patronymicName) {
        this.patronymicName = patronymicName;
    }

    @Basic
    @Column(name = "Pol", nullable = true, length = 3)
    public String getPol() {
        return pol;
    }

    public void setPol(String pol) {
        this.pol = pol;
    }

    @Basic
    @Column(name = "DateBirth", nullable = true)
    public Date getDateBirth() {
        return dateBirth;
    }

    public void setDateBirth(Date dateBirth) {
        this.dateBirth = dateBirth;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ChildrenEntity that = (ChildrenEntity) o;

        if (idChildren != that.idChildren) return false;
        if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;
        if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false;
        if (patronymicName != null ? !patronymicName.equals(that.patronymicName) : that.patronymicName != null)
            return false;
        if (pol != null ? !pol.equals(that.pol) : that.pol != null) return false;
        if (dateBirth != null ? !dateBirth.equals(that.dateBirth) : that.dateBirth != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = idChildren;
        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        result = 31 * result + (patronymicName != null ? patronymicName.hashCode() : 0);
        result = 31 * result + (pol != null ? pol.hashCode() : 0);
        result = 31 * result + (dateBirth != null ? dateBirth.hashCode() : 0);
        return result;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_Employee", referencedColumnName = "id_Employee")
    public EmployeeEntity getEmployeeByIdEmployee() {
        return employeeByIdEmployee;
    }

    public void setEmployeeByIdEmployee(EmployeeEntity employeeByIdEmployee) {
        this.employeeByIdEmployee = employeeByIdEmployee;
    }

    @Override
    public String toString() {
        return (getLastName() +" "+getFirstName()+" "+getPatronymicName()+", "+"Дата рождения: "+getDateBirth());
    }
}


Попробовал поставить загрузку FetchType=EAGER в сущности ChildrenEntity, но при попытке загрузить коллекцию в сущности EmployeeEntity всё равно выдаёт исключение "Exception in thread "AWT-EventQueue-0" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: Entity.EmployeeEntity.childrenByIdEmployee, could not initialize proxy - no Session" ,
а в поле коллекции сущности пишет:
Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.

@Entity
@Table(name = "children", schema = "staffdepartment", catalog = "")
public class ChildrenEntity {
    private int idChildren;
    private String firstName;
    private String lastName;
    private String patronymicName;
    private String pol;
    private Date dateBirth;
    @ManyToOne(fetch = FetchType.EAGER)
    private EmployeeEntity employeeByIdEmployee;

    @Id
    @Column(name = "id_Children", nullable = false)
    public int getIdChildren() {
        return idChildren;
    }

    public void setIdChildren(int idChildren) {
        this.idChildren = idChildren;
    }

    @Basic
    @Column(name = "FirstName", nullable = true, length = 30)
    public String getFirstName() {
        return firstName;
    }

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

    @Basic
    @Column(name = "LastName", nullable = true, length = 30)
    public String getLastName() {
        return lastName;
    }

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

    @Basic
    @Column(name = "PatronymicName", nullable = true, length = 30)
    public String getPatronymicName() {
        return patronymicName;
    }

    public void setPatronymicName(String patronymicName) {
        this.patronymicName = patronymicName;
    }

    @Basic
    @Column(name = "Pol", nullable = true, length = 3)
    public String getPol() {
        return pol;
    }

    public void setPol(String pol) {
        this.pol = pol;
    }

    @Basic
    @Column(name = "DateBirth", nullable = true)
    public Date getDateBirth() {
        return dateBirth;
    }

    public void setDateBirth(Date dateBirth) {
        this.dateBirth = dateBirth;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ChildrenEntity that = (ChildrenEntity) o;

        if (idChildren != that.idChildren) return false;
        if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;
        if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false;
        if (patronymicName != null ? !patronymicName.equals(that.patronymicName) : that.patronymicName != null)
            return false;
        if (pol != null ? !pol.equals(that.pol) : that.pol != null) return false;
        if (dateBirth != null ? !dateBirth.equals(that.dateBirth) : that.dateBirth != null) return false;
        return true;
    }

    @Override
    public int hashCode() {
        int result = idChildren;
        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        result = 31 * result + (patronymicName != null ? patronymicName.hashCode() : 0);
        result = 31 * result + (pol != null ? pol.hashCode() : 0);
        result = 31 * result + (dateBirth != null ? dateBirth.hashCode() : 0);
        return result;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "id_Employee", referencedColumnName = "id_Employee")
    public EmployeeEntity getEmployeeByIdEmployee() {
        return employeeByIdEmployee;
    }

    public void setEmployeeByIdEmployee(EmployeeEntity employeeByIdEmployee) {
        this.employeeByIdEmployee = employeeByIdEmployee;
    }

    @Override
    public String toString() {
        return (getLastName() +" "+getFirstName()+" "+getPatronymicName()+", "+"Дата рождения: "+getDateBirth());
    }
}

Ответов: 1

1
12 янв 2019 13:04
Ленивая загрузка как раз в том и состоит, что связь не подгружается в изначальном запросе. Затем если она понадобится и к элементам коллекции обращаются - тогда только коллекция подгружает в себя элементы. В твоем случае это происходит уже после того как Session/EntityManager был закрыт, ну и в итоге получается исключение из-за этого. Нужно работать с коллекцией до того как была закрыта сессия.

Если хочешь загрузить коллекцию сразу в изначальном запросе, то нужно либо добавлять в запрос fetch join, либо все же делать FetchType=EAGER.
Модераторы: Нет
Сейчас эту тему просматривают: Нет