簡體   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