Ich habe gerade Hibernate's optimistisches Locking letzte Woche gelernt und es in meine Anwendung eingeführt, die mit Spring JPA und MySQL DB geschrieben wurde.optimistische Sperrung fehlgeschlagen; verschachtelte Ausnahme ist org.hibernate.StaleObjectStateException, wenn ich einen Datensatz mit Spring Data's CrudRepository erhalte
Meine Entity wie folgt aussieht, wurde die Version
Anmerkung gerade hinzugefügt,
@Entity
public class Instance {
...
@javax.persistence.Version
private Date updateTime;
...
pubic Instance() {
this.updateTime = new Date();
}
}
Und ich habe eine org.springframework.data.repository.CrudRepository
für persistierende der Daten verwendet. Während ich verified Aktualisierung bestehende Rekord funktioniert gut, ist das Problem, es Ausnahme auslösen würde, wenn ein neues Objekt persistierenden
inst = new Inst();
instanceRepo.save(inst);
Die geworfene Ausnahme
org.springframework.orm.ObjectOptimisticLockingFailureException: Object of class [Instance] with identifier [a5deddb9-d76c-433f-8b0d-e50cbf8f601e]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) :
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2541)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3285)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3183)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3525)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:159)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:465)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:351)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1258)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:177)
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:77)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
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)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:131)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy139.save(Unknown Source)
ist Dies ist einfach der erste Persistenz Anruf und ich glaube nicht, dass es mehrere Threads gibt, die versuchen, diesen Datensatz zu aktualisieren, also bin ich verwirrt, warum diese Ausnahme ausgelöst wird.
Auch habe ich versucht, in den zugrunde liegenden Code zu verfolgen, und hier ist einige Erkenntnisse hilfreich sein könnten,
Wenn die zugrunde liegende
org.springframework.data.jpa.repository.support.SimpleJpaRepository#save(S)
Aufruf wie unten eingefügt, geht der Code in die Zusammenfassungslogik, obwohl diese ist ein neuer Datensatz,public <S extends T> S save(S entity) { if (entityInformation.isNew(entity)) { em.persist(entity); return entity; } else { return em.merge(entity); } }
eine Ausnahme tritt auf, wenn es um die Transaktion zu verpflichten versucht und die DB zu spülen.
ist nicht das, was sollte, falls Sie zufällig eine abgestandene bezwecken .. das ist, warum wir die optimistische Sperren benutzen? – Zulfi