开发者

Hibernate: Prevent update of dirty instances that were never update()'ed manually in the session

I am encountering a behaviour of Hibernate of which I don't know if its a feature or a bug/wrong usage of hibernate in my code.

The FlushMode of my session it set to FlushMode.AUTO. If I execute a select query the hibernate autoflush procedure jumps in and tries to update an entity because it thinks that its dirty. However, I am not calling update() for this entity somewhere in my session and I even think I am not modifying it, not even due to cascading. The result is that the dirty entity that is automatically updated causes my database to be in an unwanted state. I am tracking this unwanted update of the entity with an SaveUpdate entity listener.

I am gathering all this information from the stacktrace (I show you an excerpt, my above stated theory might be wrong ;))

2011-06-24 09:51:07,790 28671957 (SaveUpdateEventListener.java:140) FATAL  - Stacktrace from last unwanted update
java.lang.Exception
    at a.b.dao.listener.SaveUpdateEventListener.checkEntity(SaveUpdateEventListener.java:138)
    at a.b.dao.listener.SaveUpdateEventListener.onSaveOrUpdate(SaveUpdateEventListener.java:38)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
    at org.hibernate.engine.CascadingAction$5.cascade(Casca开发者_如何学编程dingAction.java:241)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:292)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:240)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:193)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:154)
    at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
    at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:997)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1142)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:921)
    at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:1)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
    at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
    at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
    >> at a.b.dao.pricing.PricingDao.list(PricingDao.java:36) << THE SELECT STATEMENT
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
    ...

So, is the automatic update of dirty fields a feature? If yes, is it caused by FlushMode.AUTO and will I be able to disable this feature with FlushMode.MANUAL?


You must be doing something to the objects in question that make Hibernate perceive them as dirty. Rather than trying to break normal Hibernate behavior, try finding a bug/misusage of Hibernate in your code.

Alternatively, if you absolutely don't need Hibernate session's intelligence for detecting dirty objects and issuing inserts, updates and deletes based on that, consider using Hibernate stateless session.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜