[英]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.