论坛首页 Java企业应用论坛

Spring中简单的保存父子关系出错!?仍然要关心Session的关闭问题

浏览 5510 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-01-10  
我看了论坛上Spring和Hibernate结合的例子,都是比较简单的用 HibernateTempate完成一个功能,那是没有问题的,可是有谁试过连续用几次HibernateTemplate更新持久和保存临时对象呢? 我这里保存一对父子关系没有通过测试,代码如下: (父子关系中的集合设置成cascade=all)

public boolean insertArticle(Article a, User u);{ 
      boolean  obj_id = false; 
       
    
         User user=null; 
         Object o=null; 
         try { 
            o = this.getHibernateTemplate();.createQuery(this.getSession();, 
                  "from User u where u.userName='" + u.getUserName(); + "'"); 
                  .uniqueResult();; 
         } catch (HibernateException e2); { 
            // TODO Auto-generated catch block 
            e2.printStackTrace();; 
         } 
         if(null!=o);{ 
            user=(User);o; 
         } 
         a.setUser(user);; 
         Set articleSet=user.getArticleSet();; 
          
         if(null!=articleSet);{ 
            articleSet.add(a);; 
         }else{ 
            articleSet=new HashSet();; 
            articleSet.add(a);; 
         } 
         user.setArticleSet(articleSet);; 
          
         try { 
             
            this.getHibernateTemplate();.update(user);; 
            obj_id=true; 
         } catch (DataAccessResourceFailureException e); { 
                     e.printStackTrace();; 
         }  catch (IllegalStateException e); { 
                      e.printStackTrace();; 
         }           


测试的时候报错:
org.springframework.orm.hibernate.HibernateSystemException: Illegal attempt to a 
ssociate a collection with two open sessions; nested exception is net.sf.hiberna 
te.HibernateException: Illegal attempt to associate a collection with two open s 
essions 
net.sf.hibernate.HibernateException: Illegal attempt to associate a collection w 
ith two open sessions 
        at net.sf.hibernate.collection.PersistentCollection.setCurrentSession(Pe 
rsistentCollection.java:257); 
        at net.sf.hibernate.impl.OnUpdateVisitor.processCollection(OnUpdateVisit 
or.java:38); 
        at net.sf.hibernate.impl.AbstractVisitor.processValue(AbstractVisitor.ja 
va:69); 
        at net.sf.hibernate.impl.AbstractVisitor.processValues(AbstractVisitor.j 
ava:36); 
        at net.sf.hibernate.impl.AbstractVisitor.process(AbstractVisitor.java:93 
); 
        at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:14 
56); 
        at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1470); 
        at net.sf.hibernate.impl.SessionImpl.update(SessionImpl.java:1355); 
        at org.springframework.orm.hibernate.HibernateTemplate$15.doInHibernate( 
HibernateTemplate.java:339); 
        at org.springframework.orm.hibernate.HibernateTemplate.execute(Hibernate 
Template.java:176); 
        at org.springframework.orm.hibernate.HibernateTemplate.update(HibernateT 
emplate.java:336); 
        at lyo.hotmail.site.service.ForumDAOImpl.insertArticle(ForumDAOImpl.java 
:139); 
        at lyo.hotmail.site.action.PostArticleController.handleRequest(PostArtic 
leController.java:74); 
        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.ha 
ndle(SimpleControllerHandlerAdapter.java:44); 
        at org.springframework.web.servlet.DispatcherServlet.doService(Dispatche 
rServlet.java:495); 
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer 
vlet.java:321); 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:802); 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl 
icationFilterChain.java:237); 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF 
ilterChain.java:157); 
        at lyo.hotmail.site.util.HiberFilter.doFilter(HiberFilter.java:50); 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl 
icationFilterChain.java:186); 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF 
ilterChain.java:157); 
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV 
alve.java:214); 
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv 
eContext.java:104); 
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav 
a:520); 
        at org.apache.catalina.core.StandardContextValve.invokeInternal(Standard 
ContextValve.java:198); 
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV 
alve.java:152); 
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv 
eContext.java:104); 
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentica 
torBase.java:462); 
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv 
eContext.java:102); 
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav 
a:520); 
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j 
ava:137); 
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv 
eContext.java:104); 
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j 
ava:118); 
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv 
eContext.java:102); 
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav 
a:520); 
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal 
ve.java:109); 
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv 
eContext.java:104); 
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav 
a:520); 
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929); 

        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:16 
0); 
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java 
:799); 
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce 
ssConnection(Http11Protocol.java:705); 
        at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java 
:577); 
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP 
ool.java:684); 
        at java.lang.Thread.run(Thread.java:534); 


HibernateTemplate不是只打开一个Session么?照以前的理解,用了Spring,就几乎不需要关系Hibernate的Session打开关闭问题,但是这里为什麽说打开了两个Session呢? 难道和这个方法有关?
 o = this.getHibernateTemplate();.createQuery(this.getSession();, 
                  "from User u where u.userName='" + u.getUserName(); + "'"); 

this.getSession()是必须的参数,我试过了即使这里加上 this.getSession().close();也不行,会报错说 "session is not open or is closed ".
后来我把代码改成这样:
public boolean insertArticle(Article a,User u); { 
      Session s = null; 
      Transaction t = null; 
      boolean  obj_id = false; 
       
      s=this.getSession();; 
         User user=null; 
         Object o=null; 
         try { 
            o = s.createQuery( 
                  "from User u where u.userName='" + u.getUserName(); + "'"); 
                  .uniqueResult();; 
         } catch (HibernateException e2); { 
            // TODO Auto-generated catch block 
            e2.printStackTrace();; 
         } 
         if(null!=o);{ 
            user=(User);o; 
         } 
         a.setUser(user);; 
         Set articleSet=user.getArticleSet();; 
          
         if(null!=articleSet);{ 
            articleSet.add(a);; 
         }else{ 
            articleSet=new HashSet();; 
            articleSet.add(a);; 
         } 
         user.setArticleSet(articleSet);; 
          
         try { 
             
                         
            s.update(user);; 
            obj_id=true; 
         } catch (DataAccessResourceFailureException e); { 
            // TODO Auto-generated catch block 
            e.printStackTrace();; 
         }  catch (IllegalStateException e); { 
            // TODO Auto-generated catch block 
            e.printStackTrace();; 
         } catch (HibernateException e); { 
            // TODO Auto-generated catch block 
            e.printStackTrace();; 
         } finally{ 
            try { 
               s.close();; 
            } catch (HibernateException e1); { 
               // TODO Auto-generated catch block 
               e1.printStackTrace();; 
            } 
         } 
          
       
      return obj_id; 

   } 

现在就是简单的用Session! 是不报错了,但是根本没有数据存入数据库.然后我手工保存子对象,用代码:
this.getHibernateTemplate();.save(a);;

又报错,说"can't commit when defaultAutoCommit is true!"

我把配置文件中的defaultAutoCommit 设置成 false,这样操作没有报错,但是数据库中仍然没有数据.
使用Spring居然到了进退两难的地步!哪位熟悉Spring的朋友能解释一下?先谢了!
   发表时间:2005-01-10  
因为在查询里提供了session,而不是通过实现spring提供的HIbernateCallBack。
而在update里,spring里会自动的创建session.这就有两个session尝试关联到同一个对象,所以例外。

使用hibernateTemplate 要使用HIbernateCallBack ,才会管理session.
0 请登录后投票
   发表时间:2005-01-11  
nihongye 写道
因为在查询里提供了session,而不是通过实现spring提供的HIbernateCallBack。
而在update里,spring里会自动的创建session.这就有两个session尝试关联到同一个对象,所以例外。

使用hibernateTemplate 要使用HIbernateCallBack ,才会管理session.


但是我在
Session s=this.getSession();;
this.getHibernateTemplate();.createQuery(s,"from..... ");; 
后面 增加了
s.close();;

仍然不行!又说明什么?按道理说我这样作是关闭了第一个Session,后来又用getHibernateTeamplate 创建了一个新的, 为什么报错说 "No session or Session is closed " ?
0 请登录后投票
   发表时间:2005-01-11  
lyo:你的这个方法是在继承了HibernateDaoSupport的类里面吗?

好像没必要this.getHibernateTemplate().createQuery()这样调用的么,直接用this.getHibernateTemplate().find()这个就可以了啊,这样的化不用自己去得到session,spring自己会管理的。

还有,你的事务是怎么设置的?
0 请登录后投票
   发表时间:2005-01-19  
de3light 写道
lyo:你的这个方法是在继承了HibernateDaoSupport的类里面吗?

好像没必要this.getHibernateTemplate().createQuery()这样调用的么,直接用this.getHibernateTemplate().find()这个就可以了啊,这样的化不用自己去得到session,spring自己会管理的。

还有,你的事务是怎么设置的?


我当然继承了 HibernateDaoSupport,否则怎没可能通过编译.
find之后可以使用 uniqueResult这样方便的方法么?不行把,所以我才冒险使用createQuery得到Query接口,为的就是使用 uniqueResult.
这里我不需要事务,能够运行就可以.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics