2011-06-24 15 views
0

Hibernateの動作や、バグ/誤った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

関連する問題