我有一个设备表,我试图填充数据。该表有一个自动增量ID和一个制造商列。
我将所有制造商数据存储在名为manufacturerList的列表中。
然后我循环遍历整个列表,并为每个条目创建一个具有该条目的新Equipment对象并存储在变量temp中。在同一个循环中,我尝试使用hibernate session将temp保存到我的表中。
然而,当我运行这个时,我收到此错误
java.lang.IllegalStateException:Session / EntityManager已关闭
使用hibernate时实现此循环的正确方法是什么?
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Equipment.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try{
List<String> manufacturerList = new List<String>();
//populate the list here
//...
for (String manufacturer:manufacturerList) {
System.out.println(manufacturer);
Equipment temp = new Equipment(manufacturer);
session.beginTransaction();
session.save(temp);
session.getTransaction().commit();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
factory.close();
}
感谢。
答案 0 :(得分:1)
在循环范围内插入和删除东西,我相信使用Session正确排序hibernate的这个特定实现,以确保会话不会过早关闭,如下所示:
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Equipment.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try{
List<String> manufacturerList = new List<String>();
//populate the list here
//...
session.beginTransaction();
for (String manufacturer:manufacturerList) {
System.out.println(manufacturer);
Equipment temp = new Equipment(manufacturer);
session.save(temp);
}
session.getTransaction().commit();
} catch (IOException e) {
e.printStackTrace();
} finally {
factory.close();
}
应在将任何内容保存到会话之前启动事务。在完成所有保存后,交易将被提交。
更改为此后,程序运行时没有错误。
如果有任何我遗漏或可以优化的内容,请随时告诉我。
答案 1 :(得分:0)
您没有显示如何获得session
值。显然,您拥有的session
已关闭,或者从未正确打开过,但您的代码部分未显示。此外,您还会显示factory
的结束,但该变量不会显示在您显示的代码段中。
通常,您可以长时间保留EntityManagerFactory
,但EntityManager
个实例的生命周期应该相当短。不要将实体管理器(或Session
)重用于多个会话;在每一个之后杀死它并在需要时开始一个新的。这样可以更容易地推断开放或关闭的内容,并防止臭名昭着的会话溢出。
我们必须假设Equipment
是一个正确声明和管理的实体类型,因为这里没有显示,并且似乎与您的错误消息无关。
因此,实现循环的正确方法是在具有循环的类中的某处初始化EntityManager
,将其用于循环,并在循环后的某个时间关闭它,但是要离开{{ 1}}到它自己的逻辑流程。
另外,你没有填写一张桌子&#34;使用Hibernate或任何JPA解决方案。 Hibernate / JPA用于对象模型,而不是表模型。将您的实体类型写为对象类型(无人工&#34; ID&#34;关键字段!)。让JPA处理映射而不是代码执行它。想想对象,而不是表格。
使用JDBC比使用JPA更好地完成批量操作。 JPA用于建模实体,而不是管理数据。