繁体   English   中英

如何在Hibernate中初始化延迟加载的集合?

[英]How do you initialize a Lazily loaded collection in Hibernate?

当Hibernate延迟加载所有内容时,我对如何构造代码感到相当困惑。

现在,我得到了Could not initialize proxy - no session当我尝试将一些数据加载到对象中时Could not initialize proxy - no session异常。

当前代码如下:

时间表类

public class MyScheduler {
  private static ItemRepo repo;
  private static List<Item> myItems;

  public MyScheduler() {
    if (myItems == null) {
      repo = new MyItemHibernateRepository();
      myItems = repo.findAll();
    }
  }
  // ... rest of code

查找所有方法v.1

  @Override
  public List<Item> findAll() {
    Session session = openSession();
    List<Item> transfers = 
        (List<Item>) session.createQuery("from Items").list();
    session.close();  
    return transfers;
  }

如您所见,在这里,我尝试从数据库加载所有内容,将它们打包到列表中,然后将它们返回给调用者。 但是,当我对此进行测试时,问题在于它们实际上并没有“加载”。 我稍后在程序中尝试使用它们,但出现了“ No Session错误之一。

经过一番阅读后,似乎它们需要在关闭session之前进行初始化,因此,在关闭会话之前,我向Hibernate.initialize添加了一个调用

查找所有方法v.2

  @Override
  public List<Transfer> findAll() {
    Session session = openSession();
    List<Item> transfers = 
        (List<Item>) session.createQuery("from Items").list();

    transfers.forEach(t -> Hibernate.initialize(t));

    session.close();  
    return transfers;
  }

HibernateUtil

public class HibernateRepository {

  private static final SessionFactory sessionFactory;

  static {
    try {
            // Create the SessionFactory from standard (hibernate.cfg.xml) 
      // config file.
      sessionFactory = new AnnotationConfiguration().bunchofclasses.configure().buildSessionFactory();
    } catch (Throwable ex) {
      // Log the exception. 
      System.err.println("Initial SessionFactory creation failed." + ex);
      throw new ExceptionInInitializerError(ex);
    }
  }

  public static SessionFactory getSessionFactory() {
    return sessionFactory;
  }

  public static Session openSession() {
    return getSessionFactory().openSession();

但是,我仍然得到相同的could not initialize proxy - no Session错误。 我需要怎么做才能正确初始化它?

即使您可以使用“查找所有方法v.2”,但由于陷入了臭名昭著的Hibernate N + 1 Select问题的陷阱,因此编写该方法的方式可能也会导致性能下降。

您应该做的是更改查询,以获取会话关闭时所需的集合。

例如,假设Item具有字段Collection<OtherItem> otherItems from Items as i join fetch i.otherItems您的查询将from Items as i join fetch i.otherItems

但是请注意,上一个查询将不会返回任何没有OtherItems (如果您还希望包括这些Items ,请使用左连接提取),如果一个Item具有多个OtherItems ,则将返回多个相同的项目。

更新

正如JBNizet正确指出的那样,为了克服返回多个Items的问题,您可以使用以下查询

select distinct i from Items as i join fetch i.otherItems (或者您离开加入获取以包含Items无论它们是否具有OtherItems

暂无
暂无

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

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