Java “休眠错误”;数据库已锁定;。如何正确关闭会话?
在我的应用程序中,我打开会话,创建条件,但不关闭它。然后在另一种方法中,我再次打开会话,更新对象并接收Java “休眠错误”;数据库已锁定;。如何正确关闭会话?,java,hibernate,sqlite,session,Java,Hibernate,Sqlite,Session,在我的应用程序中,我打开会话,创建条件,但不关闭它。然后在另一种方法中,我再次打开会话,更新对象并接收数据库被锁定tr.commit() 如果我在第一个实例中放入session.close(),我将收到 无法初始化代理-没有会话 如何正确关闭和打开会话?或者我需要将代理对象复制到我创建的对象上,然后close() 我是个十足的乞丐。我使用sqlite。任何帮助都将不胜感激。提前感谢。在使用“阅读API”时,请遵循以下步骤 Hibernate会话通常绑定到线程 因此,也许您应该重新构造代码,以便在
数据库被锁定tr.commit()
如果我在第一个实例中放入session.close()
,我将收到
无法初始化代理-没有会话
如何正确关闭和打开会话?或者我需要将代理对象复制到我创建的对象上,然后close()
我是个十足的乞丐。我使用sqlite。任何帮助都将不胜感激。提前感谢。在使用“阅读API”时,请遵循以下步骤
Hibernate会话通常绑定到线程
因此,也许您应该重新构造代码,以便在处理开始时获得会话(例如,在web应用程序的ServletFilter实例中)
然后在每个方法中,您都可以使用相同的会话对象来启动新事务(当然,还可以结束事务)
public void doWork(){
Transaction tx = null;
try{
tx = session.beginTransaction();
}catch(){
} finally {
// if tx != null then.. close transaction, or rollback?
}
}
编辑:通常,在处理完成后关闭会话(在web应用中,也可以在同一个ServletFilter中)
谷歌:“在视图中打开会话”模式。原因
当您试图访问查询返回的MyDocument
类实例的属性时,可能会出现错误
默认情况下,Hibernate是惰性的。它为对象返回一个代理
,而不是在访问引用属性时访问数据库。此行为可以在需要时被覆盖。
始终记住,无法初始化代理-当代码尝试访问代理
属性(通过点击数据库)并发现会话不可用时,不会收到任何会话(由于Hibernate使用此接口访问数据库,因此需要会话)
解决方案
当Hibernate试图加载尚未加载的对象时,请确保会话处于打开状态。您如何做到这一点
(简单地说)Hibernate有两个学派:
在关闭会话或之前获取可能访问的所有数据
在处理对象的整个过程中保持会话处于打开状态
我想让你复习一些主题,比如Hibernate中的工作单元。Hibernate提供了一个极好的界面来定义数据库访问的边界。必须在这些边界之间访问(读/写)数据
hibernate.hibernate配置中的当前会话上下文类
,可以采用值jta | thread | managed | custom.class。此变量定义会话的工作单元
最后但最重要的一点是尝试使用(您必须遇到.getCurrentSession()
这有助于您获得每次在代码中任何位置打开的相同会话。Hibernate在幕后处理所有事情
希望此答案可以作为您在使用Hibernate时选择正确路径的指南,而不仅仅是解决此特定问题的指南。谢谢您的回答。如果只是从会话中创建条件会怎么样。我没有。我应该保存什么?无法初始化代理-没有会话也可能是因为其他原因。因此,请验证位置是否正确您收到了错误。您的新代码似乎很好。我使用列表文档用从条件中获得的数据填充表,无法初始化代理-表的构造函数中没有会话。谢谢您的回答。请与我一起使用。我正在制作桌面应用程序。您能进一步解释如何获取会话。我是否在初始化主f时创建会话orm?我如何在其他表单中使用它?我认为在桌面应用程序中,每个事件都会启动一个新线程,例如按钮单击。因此,可能应该在按钮单击时打开新会话。1.应在加载应用程序时创建sessionFactory。2.应创建会话(使用您正在使用的相同API)当一个新线程启动时。因此,也许你需要在EventHandler中创建一个会话。谢谢你的解释。如何检索sessionfactory和会话。我是否将它们设置为静态?我是这方面的初学者。HibernateUtil.getSessionFactory()工作正常。我需要调用一次吗?是的,调用HibernateUtil.getSessionFactory()仅在应用程序启动时调用一次。您可能需要一个负责启动应用程序的类。在Java中,该类的方法为:public static void main(String[]args)。因此,在该类中,该类应该只调用一次:,调用HibernateUtil.getSessionFactory()
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//Or any other operation.
session.save(a);
tx.commit();
session.close();
public void doWork(){
Transaction tx = null;
try{
tx = session.beginTransaction();
}catch(){
} finally {
// if tx != null then.. close transaction, or rollback?
}
}