论坛首页 Java企业应用论坛

关于inverse发表点看法

浏览 3746 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-03-20  

看了很多关于inverse的文章,理解得也不是很透彻,这次做了这个项目,遇到这方面问题,就总结了一样关于inverse的配置,

1.关系parent和children的例子也已经说了怎么去配置一对多的关系,这个例子已经说明了在set端设置inverse=true,原因很简单,child长大了,不需要什么事情都要parent带到

其实在我看来,inverse=true实际上是去解放了one那一方,在这儿就是指parent对象,他不需要在每次更新的时候,都把children都加载出来。像在下面的代码中,不会有什么问题,应该都在一个session中完成的

 ParentManager manager=(ParentManager) getBean("parentManager");
          Parent parent=manager.getParent("pppp");
          parent.setName("bob");manager.save(parent);

所以不会觉得有什么问题。但是在WEB应用的三层结构中,通常要把模型传递到表现层中,完成更新操作,那这个时候inverse=true的优势就明显了,他可以不用考虑Children就完成自身的更新

2.当inverse=false会发生什么?

那天也是无意注意到这个问题,突然把系统的所有inverse都设置成了false

当在插入一个新的对象的时候,不会出现什么问题。但是在更新父对象的时候,却发生了我不想看到的,Customer和Order是一对多的关系

Hibernate: update customer.name=?..........where customerName=? and version=?

Hibernate: update orders set customer=null where customer=?

在更新了customer信息后,同时把订单中该用户的用户置为null,换句话说就是断了两者之间的联系。再看看代码


  CustomerForm customerForm = (CustomerForm) form;
  Customer customer = new Customer();
  convertObject(customerForm, customer);
  CustomerManager manager = (CustomerManager) getBean("customerManager");                                                                           

  manage.save(customer);

customerForm是通过struts的form理到来自表单的数据。最后通过业务层的代码调用Hibernate的saveOrUpdate()方法进行保存。这个时候我发现我并未去加载和customer关系的order,

然后我修改了代码,试着把所有的该customer的order都提出来,并在保存前调用了

customer .setOrder(order);

结果发生异常


org.springframework.orm.hibernate3.HibernateSystemException: a different object with the same identifier value was already associated with the session: [com.us.ebuy.model.Customer#123]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.us.ebuy.model.Customer#123]
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.us.ebuy.model.Customer#123]
 at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:629)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:258)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:216)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
 at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:531)
 at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)
 at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:519)
 at org.springframework.orm.hibernate3.HibernateTemplate$18.doInHibernate(HibernateTemplate.java:690)
 at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:365)
 at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:687)
 at com.us.ebuy.dao.hibernate.BaseDAOHibernate.saveObject(BaseDAOHibernate.java:55)
 at com.us.ebuy.users.dao.hibernate.CustomerDAOHibernate.saveCustomer(CustomerDAOHibernate.java:64)
 at com.us.ebuy.users.service.impl.CustomerManagerImpl.saveCustomer(CustomerManagerImpl.java:52)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:585)
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
 at $Proxy2.saveCustomer(Unknown Source)
 at com.us.ebuy.users.action.CustomerAction.save(CustomerAction.java:133)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:585)
 at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:274)
 at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:194)
 at com.us.ebuy.action.BaseAction.execute(BaseAction.java:143)
 at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
 at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
 at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
 at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
 at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:75)
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
 at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
 at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
 at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
 at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
 at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
 at java.lang.Thread.run(Thread.java:595)

可以看出,在更新的时候,他执行了插入操作,才会认为有重复的key,后来我想到了使用hibernate的merge方法,通过合作,才能完成customer的更新操作,但这这种更新方法显然是我们不愿意看到的。后来通过检测配置文件才发现,set 元素的inverse=false,最后我想是这儿的原因,改为false后,还是通过saveOrUpdate()方法更新对象,问题解决了。

通过上面的问题,可以更进一步的清楚了,Hibernate在对对待持久化的对象和游离状态的对象是不一样的,上述问题通常都是发生在处理游离状态的对象时候,而在三层结构中,我们会经常处理这种问题的,看来是要重新理解对象的状态问题。

   发表时间:2007-03-20  
inverse的作用是把保存关系的一方设在inverse=false的一方,如果你在一的一方设置inverse=false,那很显然,你要想级联保存或是更新pojo时,必须session.save(parent),而不是session.save(child).否则,你的parent当然是不能保存的。
PS:这样的文章也属于高级见解?斑竹眼神还真差!
0 请登录后投票
   发表时间:2007-03-20  
呵呵,对不起,这是我学习过程中的一些总结了。
看来用见解有点夸大了,真是不好意思啊 还请多指教了
0 请登录后投票
论坛首页 Java企业应用版

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