当Hibernate加载所有内容时,我对如何构造代码感到困惑。
正如我现在所做的那样,当我尝试将一些数据加载到我的对象中时,我得到了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
错误。我需要做些什么来正确初始化它?
答案 0 :(得分:0)
即使你让Find All Method v.2工作,它的编写方式可能会给你带来不好的表现,因为你陷入了臭名昭着的Hibernate N+1 Select problem陷阱。
您应该做的是更改查询以获取会话关闭时需要的集合。
例如,让我们说Item有一个字段Collection<OtherItem> otherItems
。你的查询是
from Items as i join fetch i.otherItems
。
但是请注意,之前的查询不会返回任何不具有Items
的{{1}}(如果您想要包含这些内容,请使用左连接提取),并且会返回多个相同的如果OtherItems
有多个Item
的商品。
<强>更新强>
正如 JBNizet 正确指出的那样,为了解决返回多个OtherItems
的问题,您将使用以下查询
Items
(或者您将联系抓取包括select distinct i from Items as i join fetch i.otherItems
,无论他们是否有Items
)