Skip to content

Commit 6c2a624

Browse files
authored
Fix race conditions when creating studies (TransientPropertyValueException save before flushing) (#237)
We get the following exceptions in the logs, the client reports a red box "study has a problem please recreate" 2022-07-04 08:32:22.260 ERROR 1 --- [ool-1-thread-21] org.gridsuite.study.server.StudyService : org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity.study -> org.gridsuite.study.server.repository.StudyEntity; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity.study -> org.gridsuite.study.server.repository.StudyEntity org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity.study -> org.gridsuite.study.server.repository.StudyEntity; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity.study -> org.gridsuite.study.server.repository.StudyEntity at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:371) ~[spring-orm-5.3.18.jar:5.3.18] at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:235) ~[spring-orm-5.3.18.jar:5.3.18] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551) ~[spring-orm-5.3.18.jar:5.3.18] at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145) ~[spring-data-jpa-2.6.3.jar:2.6.3] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.18.jar:5.3.18] at com.sun.proxy.$Proxy180.findAllByNodeStudyIdAndName(Unknown Source) ~[na:na] at org.gridsuite.study.server.NetworkModificationTreeService.isNodeNameExists(NetworkModificationTreeService.java:345) ~[classes/:na] at org.gridsuite.study.server.NetworkModificationTreeService.assertNodeNameNotExist(NetworkModificationTreeService.java:338) ~[classes/:na] at org.gridsuite.study.server.NetworkModificationTreeService.lambda$createNode$2(NetworkModificationTreeService.java:146) ~[classes/:na] at java.base/java.util.Optional.map(Optional.java:265) ~[na:na] at org.gridsuite.study.server.NetworkModificationTreeService.createNode(NetworkModificationTreeService.java:145) ~[classes/:na] at org.gridsuite.study.server.NetworkModificationTreeService.createBasicTree(NetworkModificationTreeService.java:311) ~[classes/:na] at org.gridsuite.study.server.NetworkModificationTreeService$$FastClassBySpringCGLIB$$ebdcb7ad.invoke(<generated>) ~[classes/:na] at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.18.jar:5.3.18] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.18.jar:5.3.18] at org.gridsuite.study.server.NetworkModificationTreeService$$EnhancerBySpringCGLIB$$697db19c.createBasicTree(<generated>) ~[classes/:na] at org.gridsuite.study.server.StudyService.insertStudy(StudyService.java:1726) ~[classes/:na] at org.gridsuite.study.server.StudyService.insertStudyEntity(StudyService.java:1719) ~[classes/:na] at org.gridsuite.study.server.StudyService.insertStudy(StudyService.java:571) ~[classes/:na] at org.gridsuite.study.server.StudyService.createStudyAsync(StudyService.java:304) ~[classes/:na] at org.gridsuite.study.server.StudyService.lambda$createStudy$2(StudyService.java:292) ~[classes/:na] at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1736) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity.study -> org.gridsuite.study.server.repository.StudyEntity at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:151) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1626) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.query.Query.getResultList(Query.java:165) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:76) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:128) ~[spring-data-jpa-2.6.3.jar:2.6.3] at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:90) ~[spring-data-jpa-2.6.3.jar:2.6.3] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:155) ~[spring-data-jpa-2.6.3.jar:2.6.3] at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143) ~[spring-data-jpa-2.6.3.jar:2.6.3] at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137) ~[spring-data-commons-2.6.3.jar:2.6.3] at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121) ~[spring-data-commons-2.6.3.jar:2.6.3] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159) ~[spring-data-commons-2.6.3.jar:2.6.3] at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138) ~[spring-data-commons-2.6.3.jar:2.6.3] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.6.3.jar:2.6.3] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.18.jar:5.3.18] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.18.jar:5.3.18] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-5.3.18.jar:5.3.18] ... 34 common frames omitted Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity.study -> org.gridsuite.study.server.repository.StudyEntity at org.hibernate.engine.spi.CascadingActions$8.noCascade(CascadingActions.java:379) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:169) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:159) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:149) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:82) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1372) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1452) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final] ... 52 common frames omitted Signed-off-by: HARPER Jon <[email protected]>
1 parent ffac2d1 commit 6c2a624

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

src/main/java/org/gridsuite/study/server/StudyService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ public Consumer<Message<String>> consumeSaResult() {
192192
};
193193
}
194194

195+
@Autowired
196+
StudyService self;
197+
195198
@Autowired
196199
public StudyService(@Value("${backing-services.case.base-uri:http://case-server/}") String caseServerBaseUri,
197200
@Value("${backing-services.single-line-diagram.base-uri:http://single-line-diagram-server/}") String singleLineDiagramServerBaseUri,
@@ -1716,7 +1719,7 @@ private StudyEntity insertStudyEntity(UUID uuid, String userId, UUID networkUuid
17161719
Objects.requireNonNull(loadFlowParameters);
17171720

17181721
StudyEntity studyEntity = new StudyEntity(uuid, userId, LocalDateTime.now(ZoneOffset.UTC), networkUuid, networkId, caseFormat, caseUuid, casePrivate, defaultLoadflowProvider, loadFlowParameters);
1719-
return insertStudy(studyEntity, importReportUuid);
1722+
return self.insertStudy(studyEntity, importReportUuid);
17201723
}
17211724

17221725
@Transactional

0 commit comments

Comments
 (0)