论坛首页 入门技术论坛

修改带<any>关联的对象报collection was not processed by flush

浏览 3684 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-09-03  
     今天修改带<any>关联的对象报错:org.hibernate.AssertionFailure:collection was not processed by flush()!涉及到了3个对象,一个企业,一个产品,一个收藏,其中收藏里通过<any>关联着企业和产品,是对产品和企业的收藏,映射文件如下:
-----------------------TPrettyFavorite.htm.xml---------------------
<class name="TPrettyFavorite" table="cn_list_TPrettyFavorite">
  <id name="id" type="integer" column="id">
    <generator class="native"/>
  </id>
  <property name="name" column="name" type="string" not-null="false" length="255"/>
  <property name="content" column="content" type="text"/>
  <any name="favorite" meta-type="string" id-type="integer" cascade="none" lazy="false">
    <meta-value value="product" class="cn.product.TPrettyProduct"/>
    <meta-value value="enterprise" class="cn.enterprise.TPrettyEnterprise"/>
    <column name="favoriteType"/>
    <column name="favoriteId"/>
  </any>
</class>

TPrettyProduct和TPrettyEnterpirse的映射文件从略。
下面是处理修改TPrettyFavorite对象的代码:
//temp是从页面传递过来的TPrettyFavorite对象
IPrettyFavorite temp = (IPrettyFavorite) this.getTableObject();
//article是从数据库里根据temp的id load出来的TPrettyFavorite对象
IPrettyFavorite article = (IPrettyFavorite) this.getCurrentTemplate.load(TPrettyFavorite.class,new Integer(temp.getId()));
article.setContent(temp.getContent());
this.getCurrentTemplate().setFlushMode(HibernateTemplate.FLUSH_ALWAYS);
this.getCurrentTemplate().saveOrUpdate(article);
this.getCurrentTemplate().flush();
this.getCurrentTemplate().evict(article);

下面是日志里打出来的信息:
2007-09-03 18:53:52,781 ERROR [org.hibernate.AssertionFailure] - <an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)>
org.hibernate.AssertionFailure: collection was not processed by flush()
at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:144)
at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:305)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:28)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
at org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:815)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)
at org.springframework.orm.hibernate3.HibernateTemplate.flush(HibernateTemplate.java:813)
   发表时间:2007-09-04  
org.hibernate.AssertionFailure: collection was not processed by flush
At work, we ran into this Hibernate problem and it took us forever to figure out. He is a short description of the problem and the what caused it for us.

Credit for finding and resolving this goes to Rick B. and Linda R.

org.hibernate.AssertionFailure: collection was not processed by flush() ERROR [main] hibernate.AssertionFailure - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) org.hibernate.AssertionFailure: collection was not processed by flush()

We discovered that custom code was causing Hibernate to explode the object graph too late in the flush execution for the new items to be processed or ignored. Be on the watch for custom implementations of methods common to all objects such as equals(), hashCode() and comparators.

Background: We had implemented a comparator for sorting purposes. During the flush execution, Hibernate called the compare method on our comparator. A side-effect of the comparator processing caused Hibernate to instantiate additional CollectionEntry objects. Typically, for objects instantiated during the flush, Hibernate marks them so that they are ignored during the processing. These objects which were created due to our comparator processing were created too late so Hibernate was not able to mark to be ignored. During postFlush it saw the objects in the collection but since they were not flagged as processed, nor flagged to be ignored the exception was thrown. The expected persistence was working correctly, however this exception was being thrown on numerous test cases.

We resolved the problem by testing for object identity (obj1 == obj2) at the beginning of the compare method. By doing this first and exiting when equal, the side-effect of lazy loading child objects is avoided in the comparator, which keeps Hibernate from instantiating unnecessary CollectionEntry objects for them. In general, following this best practice with comparators will ensure better performance as well (Refer to Effective Java chapter 3.)
0 请登录后投票
   发表时间:2007-09-04  
这种问题太幼稚了!
0 请登录后投票
   发表时间:2007-09-04  
hibernate的官方网站说这个是一个bug,是在更新any的关联的时候的问题,在3.2版本已经修正了!
0 请登录后投票
   发表时间:2007-09-04  
0 请登录后投票
论坛首页 入门技术版

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