繁体   English   中英

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

[英]Not able to fetch data using lazy loading in hibernate

嗨,我正尝试在休眠模式下编写代码以延迟加载具有以下架构的表员工的数据。 但是出现一个异常,表明该会话不可用。 谁可以帮我这个事。 提前致谢。

  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
  );

步骤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();
    }
}

步骤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
}

第3步:我试图找到一名员工的下属。 就像雇员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;
}

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

暂无
暂无

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

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