我正在尝试更新hibernate会话中的表,然后通过重新获取hibernate表来刷新本地数据表。如果我不进行更新,我可以毫无问题地刷新本地数据表,但是当我添加更新时,我在服务器日志中收到以下错误:
SEVERE:org.hibernate.SessionException:会话已关闭!
任何人都可以给我一个关于我做错了什么的建议以及我可以做些什么来解决这个问题?
感谢。
以下是执行更新的代码。它似乎工作正常,因为我没有得到任何异常,我得到一个返回值为1,表明该表已更新并提交。
public int updatePolygonGroupAtrributes( long id, String groupName, String color, long ownerId, int updtUserId )
{
int stat = 0;
TbPolygonGroup polyGroup = null;
TbCustAccount custAcct = null;
TbUser user = null;
try
{
org.hibernate.Transaction tx = session.beginTransaction();
polyGroup = (TbPolygonGroup)session.get(TbPolygonGroup.class, id);
polyGroup.setVcPolygonGroup(groupName);
polyGroup.setVcColor(color);
custAcct = (TbCustAccount)session.get(TbCustAccount.class, ownerId);
System.out.println( "<DbHelper.updatePolygonGroupAtrributes> ownerId = "+custAcct.getBiAccountId()+", Name = "+custAcct.getVcCustAccountName() );
polyGroup.setTbCustAccount(custAcct);
polyGroup.setDtUpdTime( new Date() );
user = (TbUser)session.get(TbUser.class, updtUserId);
System.out.println( "<DbHelper.updatePolygonGroupAtrributes> update User Id = "+user.getIuserId()+", Name = "+user.getVcUserFirstName()+" "+user.getVcUserLastName() );
polyGroup.setTbUser(user);
try
{
session.update(polyGroup);
tx.commit();
stat = 1;
}
catch(Exception e)
{
tx.rollback();
e.printStackTrace();
status = e.getMessage();
stat = -1;
}
}
catch( Exception ex )
{
ex.printStackTrace();
status = ex.getMessage();
stat = -1;
}
return stat;
}
以下是我在我的应用程序中调用更新的代码(除了显示我正在做的事情之外,这些代码并不相关)。
public void polyGroupUpdateAction()
{
int changed = 0;
String clr = "#"+polyColor;
long ownId = sb1.getLong( selectedPolyOwner, 0 );
long groupId = selectedPolygonGroup.getBiPolygonGroupId();
int updUserId = sb1.getLoginUserId();
int retVal = dbHelper.updatePolygonGroupAtrributes(groupId, polyName, clr, ownId, updUserId);
if( retVal < 0 )
{
sb1.setMessage( "Error updating Polygon Group: "+dbHelper.getStatus() );
return;
}
System.out.println("---------<DeviceSessionBean.polyGroupUpdateAction> Return value = "+retVal);
sb1.setMessage("Polygon Group has been updated.");
fillPolyGroupList();
return;
}
以下是重新填充本地表格的相关代码(显示错误发生的位置)
public void fillPolyGroupList()
{
System.out.println( "<DeviceSessionBean.fillPolyGroupList> Entering ... ");
tbPolygonGroupList = dbHelper.getPolygonGroup();
System.out.println( "<DeviceSessionBean.fillPolyGroupList> After reloading polygon group list ... ");
polygonGroupDataModel = new PolygonGroupDataModel(tbPolygonGroupList);
}
以下是显示更新成功返回的会话日志,但是当我尝试在fillPolyGroupList()中重新读取数据表时出现错误;
INFO: <DbHelper.updatePolygonGroupAtrributes> ownerId = 74, Name = TransCore - David Kerr
INFO: <DbHelper.updatePolygonGroupAtrributes> update User Id = 2, Name = Transcore System
INFO: ---------<DeviceSessionBean.polyGroupUpdateAction> Return value = 1
INFO: <DeviceSessionBean.fillPolyGroupList> Entering ...
SEVERE: org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1319)
.....
at java.lang.Thread.run(Thread.java:662)
INFO: <DeviceSessionBean.fillPolyGroupList> After reloading polygon group list ...
WARNING: #{deviceSessionBean.polyGroupUpdateAction}: java.lang.NullPointerException
javax.faces.FacesException: #{deviceSessionBean.polyGroupUpdateAction}: java.lang.NullPointerException
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
....
答案 0 :(得分:1)
我尝试了建议的解决方案并将模式更改为“手动”而不是“线程”,并在我访问hibernate的96个方法中执行openSession()和closeSession()。那没用。在对访问方法进行了几次调用之后,我遇到了“无会话”错误。因此,该解决方案由于某种原因不起作用,更不用说它增加了许多不必要的开销,因为96种方法中只有3种实际上进行了更新。
因此,我没有用开放/关闭会话代码包装所有方法,而是通过在commit()之后重新打开会话来获得正确的结果。
在上面的代码中,我有一行:
tx.commit();
我发现如果我在此之后添加一个openSession(),我会得到我想要的结果。所以上面的代码已从上面的tx.commit()更改为:
tx.commit();
this.session - HibernateUtil.getSessionFactory().openSession();
我只需要将其添加到实际执行更新的3(此时)方法,而其他93(此时)方法可以保持为写入而无需
答案 1 :(得分:0)
当你在Hibernate会话中提交事务时 自动关闭会话意味着它无法重复使用。
http://www.17od.com/2006/11/06/using-managed-sessions-in-hibernate-to-ease-unit-testing/
在我的链接上,它还解释了如何手动控制会话,以便在函数上测试然后修改所有内容:)
如果你是hibernate的新手,你最好尝试从maven原型开始你的项目,这将为你提供一个体面的项目结构,例如已配置的hibernate / spring。
安装maven,键入mvn archetype:generate,选择要使用的技术。然后键入mvn eclipse:eclipse在新项目上生成eclipse配置文件,最后将其导入eclipse。 它将帮助您通过设置完整堆栈来开始。 (ex原型appfuse-basic-spring将使用SpringMVC,Spring和Hibernate创建一个应用程序)