简体   繁体   English

无法在休眠中使用延迟加载获取数据

[英]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 步骤1:我的休眠配置如下

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 步骤2:休眠映射如下

@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. 第3步:我试图找到一名员工的下属。 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. 就像雇员e1的经理ID为1一样,则emp e1是雇员m1的下属,雇员m1的employee_id为1。我在dao类中编写了以下代码。

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. 运行DAO类的getSubOrdinates()方法后,出现错误,提示会话不可用。

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. Hibernate返回延迟加载的集合的代理对象。 In your case subOrdinates = emp.getSubOrdinates(); 在您的情况下, 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. 您可能正在此方法之外使用此Set,并且因为Session已在此方法中关闭,它将引发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. 一种方法是将Service方法包装在事务中,另一种方法是仅迭代getSubOridinate方法中的Set,或者可以使用HQL覆盖查询中的延迟加载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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