2017-02-15 7 views
0

例外が発生しています。私はスプリングデータJPAを使用しています& & Hibernate いくつかのエンティティとクエリにいくつかの更新を行うメソッドがあります。 トランザクションが終了する前で、myRespositoryEntity.save(myEntity)を呼び出す前に、トランザクションの一貫性を維持するため、hibernate/jpaがフラッシュを実行し、このフラッシュでマージの代わりにpersistを実行しようとしているようです。 私はいくつかの分離されたエンティティを持っていることを知っていますが、この例外はフラッシュして保存しないときに何が起こりますか?トランザクションの早い段階でエンティティを保存しようとすると、例外は発生しません。フラッシュ時に分離されたエンティティ

私はDTOからEntitiesオブジェクトに変換し、いくつかの既存のオブジェクトはエンティティマネージャに配置されないため、エンティティを分離しました。しかし、私はこのランダムなフラッシュ動作を取得していない場合は、マージはすぐにものを行うだろう

いずれかの回避策?何か案は?

Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: package.MyEntity 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139) 
    at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:838) 
    at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:831) 
    at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:357) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) 
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379) 
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:167) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:158) 
    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91) 
    at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:61) 
    at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1227) 
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1293) 
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) 
    at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) 
    at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:495) 
    at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:71) 
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:206) 
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:78) 
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:102) 
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:92) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    ... 130 common frames omitted 

答えて

1

HibernateはデフォルトでFlushMode.AUTOを使用するため、この動作が観察されます。

基本的にFlushMode.AUTOが設定されている場合、Hibernateは、クエリ操作を実行する前にセッション内のエンティティ状態がダーティであるかどうかをチェックします。汚れた状態が検出された場合、状態をフラッシュして、その変更がクエリ結果に反映されるようにすることができます。

側の注意点として、Hibernateは常に、フラッシングを避けるためにいくつかの最適化を持っているあなたが実行しているクエリは、フラッシュモードを変更することで、この動作を無効にすることができた結果

に影響を与える任意の汚れたエンティティ状態を持つべきではありませんタイプはCOMMITです。これは基本的に、トランザクションがコミットするまで、Hibernateがデータベースの変更をフラッシュしないようにします。これはあなたの使用に基づいていくつかの望ましくない副作用を持つ可能性がありますので、あらかじめご注意ください。

もし可能であれば、絶対に必要な場合を除き、FlushModeだけを残しておき、できる限りエンティティを永続化またはマージする前に、データベースからすべてのエンティティ状態を収集するようにリポジトリコードを最適化することをお勧めします。

関連する問題