2011-06-24 57 views
0

我遇到了Hibernate的行爲,我不知道它的功能或Hibernate的錯誤/錯誤用法碼。休眠:防止在會話中手動更新從未更新()的髒實例

我的會議的FlushMode設置爲FlushMode.AUTO。如果我執行select查詢,hibernate autoflush過程會跳入並嘗試更新實體,因爲它認爲它是髒的。但是,我並沒有在會話中的某個地方爲此實體調用update(),我甚至認爲我沒有修改它,即使是級聯也不行。 結果是自動更新的髒實體導致我的數據庫處於不需要的狀態。我正在用SaveUpdate實體監聽器跟蹤這個不需要的實體更新。

我收集來自堆棧跟蹤所有這些信息(我會告訴你的摘錄,我上述的理論可能是錯誤的;))

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(CascadingAction.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) 
    ... 

因此,是髒的字段的自動更新功能?如果是,是由FlushMode.AUTO引起的,我能否使用FlushMode.MANUAL禁用此功能?

回答

4

你必須對那些讓Hibernate認爲它們很髒的對象做些事情。與其試圖破壞正常的Hibernate行爲,不如嘗試在代碼中發現Hibernate的錯誤/錯誤。或者,如果您絕對不需要Hibernate會話的智能來檢測髒對象併發出插入,更新和基於此的刪除,請考慮使用Hibernate無狀態會話。

+0

有沒有辦法查看哪個屬性確實被標記爲髒?我看了一下這個骯髒的攔截器,但我想我仍然需要知道Hibernate如何比較屬性 – Erik

+0

最好的辦法是在一個非常有限的會話中重現此問題,只有少數Hibernate會話緩存中的對象並逐步完成代碼。你可能想看看這篇文章:http://blog.xebia.com/2009/04/why-did-hibernate-update-my-database/ – Olaf

+0

這可能是一個應該去的地方。問題是這個環境是一個服務器在高負載下運行多個線程:/ – Erik