java – Hibernate:“会话已关闭”,但从未关闭(手动)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – Hibernate:“会话已关闭”,但从未关闭(手动),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4943字,纯文字阅读大概需要8分钟。
内容图文
![java – Hibernate:“会话已关闭”,但从未关闭(手动)](/upload/InfoBanner/zyjiaocheng/776/d46e7b67daf04f54a4b939bbd806b2cf.jpg)
我在这里遇到了一个非常奇怪的问题,我完全不明白为什么会这样.
问题看起来像这样:
我有一个叫做“SmampiAccount”的课程,里面有一个电子邮件帐户列表.映射文件看起来像这样(缩短):
<hibernate-mapping>
<class name="com.smampi.web.model.account.SmampiAccount" table="SMAMPIACCOUNT">
<id name="id" type="long" access="field">
<column name="SMAMPI_ACCOUNT_ID" />
<generator class="native" />
</id>
<bag name="mailAccounts" table="MAILACCOUNTS" lazy="false" inverse="true">
<key column="SMAMPI_ACCOUNT_ID"></key>
<one-to-many class="com.smampi.web.model.mail.account.MailAccount"/>
</bag>
</class>
</hibernate-mapping>
我通过这个方法得到了这个类的实例:
public SmampiAccount loadSmampiAccount(long id) throws FailedDatabaseOperationException {
SmampiAccount smampiAccount = null;
Session session = null;
Transaction transaction = null;
try {
session = getSession();
transaction = session.beginTransaction();
smampiAccount = (SmampiAccount) session.load(com.smampi.web.model.account.SmampiAccount.class, id);
List<MailAccount> mailAccounts = smampiAccount.getMailAccounts();
doSomething(mailAccounts);
transaction.commit();
} catch (Exception e) {
rollback(transaction);
closeSession();
throw new FailedDatabaseOperationException(e);
} finally {
closeSession();
}
return smampiAccount;
}
private Session getSession() {
if (_session == null) {
_session = getSessionFactory().openSession();
}
if (_session.isOpen() == false) {
_session = getSessionFactory().openSession();
}
return _session;
}
这样可以正常工作.
现在,我想为映射文件添加一个新属性,以便保存对默认电子邮件帐户的引用:
<many-to-one name="defaultMailAccount" column="DEFAULT_MAIL_ACCOUNT_ID" />
现在,我在此行的方法public SmampiAccount loadSmampiAccount(long id)中得到一个例外:
List<MailAccount> mailAccounts = smampiAccount.getMailAccounts();
堆栈跟踪:
org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.getPersistenceContext(SessionImpl.java:1954)
at org.hibernate.event.def.DefaultPostLoadEventListener.onPostLoad(DefaultPostLoadEventListener.java:49)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:250)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
at org.hibernate.loader.Loader.doQuery(Loader.java:857)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2037)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3293)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:147)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:1026)
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.smampi.web.model.account.SmampiAccount_$$_javassist_19.getMailAccounts(SmampiAccount_$$_javassist_19.java)
这怎么可能?
会话未手动关闭,并且尚未调用.commit()(通常会关闭会话).
另外一种方法也不可能在这里干扰因为我为每个方法调用创建了一个新的hibernate会话,这个方法专用于这个方法.
编辑
我在会话打开状态中添加了一些调试信息:
session = getSession();
System.err.println(session.isOpen());
transaction = session.beginTransaction(); // 1 (true)
System.err.println(session.isOpen()); // 2 (true)
smampiAccount = (SmampiAccount) session.load(com.smampi.web.model.account.SmampiAccount.class, id);
System.err.println(session.isOpen()); // 3 (true)
List<MailAccount> mailAccounts = smampiAccount.getMailAccounts(); // Throws exception that session is closed
doSomething(mailAccounts);
System.err.println(session.isOpen()); // 4 (not called)
transaction.commit();
这给了我:
true
true
true
org.hibernate.SessionException: Session is closed!
解决方法:
我是世界上最大的白痴.
在defaultMailAccount的setter中,我有这个:
public void setDefaultMailAccount(MailAccount defaultMailAccount) {
this.defaultMailAccount = defaultMailAccount;
try {
databasecontroller.update(this);
} catch (FailedDatabaseOperationException e) {
handleException(e, false, null, null);
}
}
每当Hibernate试图从数据库加载持久版本并再次导致会话关闭时,对databasecontroller.update(this)的调用就会导致级联.
将databasecontroller.update(..)的调用移到该方法之外修复了该问题.
对不起,大家都花时间感谢您的帮助!
内容总结
以上是互联网集市为您收集整理的java – Hibernate:“会话已关闭”,但从未关闭(手动)全部内容,希望文章能够帮你解决java – Hibernate:“会话已关闭”,但从未关闭(手动)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。