简体   繁体   中英

Not able to fetch data using lazy loading in hibernate

Hi I am trying to write a code in hibernate to lazy load the data for a table employee which is having the below schema. But getting an exception saying that session is not available. Can anyone help me on this. Thanks in advance.

  CREATE TABLE employees
  (
    employee_id NUMBER 
                GENERATED BY DEFAULT AS IDENTITY START WITH 108 
                PRIMARY KEY,
    first_name VARCHAR( 255 ) NOT NULL,
    last_name  VARCHAR( 255 ) NOT NULL,
    email      VARCHAR( 255 ) NOT NULL,
    phone      VARCHAR( 50 ) NOT NULL ,
    hire_date  DATE NOT NULL          ,
    manager_id NUMBER( 12, 0 )        , -- fk
    job_title  VARCHAR( 255 ) NOT NULL,
    CONSTRAINT fk_employees_manager 
        FOREIGN KEY( manager_id )
        REFERENCES employees( employee_id )
        ON DELETE CASCADE
  );

Step 1: My hibernate configuration is as below

public class Config {
    private static final SessionFactory sessionFactory;
    static {
        try {
            Properties properties = new Properties();
            properties.setProperty("hibernate.connection.url", "jdbc:oracle:thin:@localhost:1521:orcl");
            properties.setProperty("hibernate.connection.username", "ot");
            properties.setProperty("hibernate.connection.password", "yourpassword");
            properties.setProperty("dialect", "org.hibernate.dialect.OracleDialect");
            properties.setProperty("hibernate.hbm2ddl.auto", "validate");
            properties.setProperty("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver");
            sessionFactory = new Configuration()
                    .addProperties(properties)
                    .addAnnotatedClass(Employee.class)
                    .buildSessionFactory();
        }catch(Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Session getSession() throws Exception{
        return sessionFactory.openSession();
    }
}

Step 2: Hibernate mapping is done as below

@Entity
@Table(name="Employees")
public class Employee {

    @Id
    @Column(name="employee_id")
    private int employeeId;

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

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

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

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

    @Column(name="hire_date")
    @Temporal(TemporalType.DATE)
    private Date hireDate;

    @ManyToOne(cascade= {CascadeType.ALL})
    @JoinColumn(name="manager_id")
    private Employee manager;

    @OneToMany(mappedBy="manager", fetch=FetchType.LAZY)
    private Set<Employee> subOrdinates = new HashSet<Employee>();

    @Column(name="job_title")
    private String jobTitle;

    //getters and setters
}

Step 3: I am trying to get the sub-ordinate of an employee. like if an employee e1 has a manager id of 1, then the emp e1 is the sub-ordinate of the employee m1 whose employee_id is 1. I have written the below code in the dao class.

public Set<Employee> getSubOrdinates(int id) {
    Set<Employee> subOrdinates = null;
    try {
        Session session = Config.getSession();
        Transaction transaction = session.beginTransaction();
        Employee emp = session.get(Employee.class, id);
        subOrdinates = emp.getSubOrdinates();
        transaction.commit();
        session.close();
    }catch(Exception e) {
        e.printStackTrace();
    }
    return subOrdinates;
}

After running the method getSubOrdinates() of DAO class, it is giving me the error saying session is not available.

INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.buynow.entity.Employee.subOrdinates, 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.PersistentSet.iterator(PersistentSet.java:188)
    at com.buynow.driver.EmployeeDriver.main(EmployeeDriver.java:12)

Hibernate returns the Proxy Object for lazy loaded collection. In your case subOrdinates = emp.getSubOrdinates(); will return a Proxy. and it will not load data until you iterate through it. You might be using this Set outside of this method and because Session is already closed in this method It will throw Exception. One method is to wrap you Service method in a transaction and other is to iterate through the Set in the getSubOridinate method only or you can use HQL to override the Lazy loading in the query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM