Я разрабатываю отдельное приложение со следующим стеком технологий:
- Spring Boot версии 2.1.0. RELEASE
- Система Oracle12c с драйвером ojdbc6 (11.2.0.3)
- Apache Camel
- JPA для основного источника данных
- JDBC для вторичного источника данных (только для чтения)
Основная цель этого приложения - опросить CSV-файлы из каталога, выполнить некоторые преобразования и сохранить соответствующие данные в базе данных Oracle. После того, как файл был опрошен с помощью верблюжьего компонента File2, все следующие маршруты используют JPA-компонент для опроса объектов, соответствующих определенному статусу.
Вот соответствующие сущности JPA:
ExchangeEntity: (эта сущность представляет один CSV-файл)
@Entity
@Table(name = "T_EXCHANGE")
@Getter
@NoArgsConstructor
public class ExchangeEntity {
public enum Status {
NEW,
PROCESSING,
PROCESSING_ABORTED,
PROCESSING_COMPLETED_WITH_ERRORS,
PROCESSING_COMPLETED_WITHOUT_ERRORS,
RELOCATION_FAILURE
}
@Id
@Type(type = "uuid-char")
@Column(name = "exchange_id", updatable = false)
@GeneratedValue(generator = "uuid")
@GenericGenerator(name="uuid", strategy = "org.hibernate.id.UUIDGenerator")
@Setter
private UUID id;
@Setter
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "status")
private Status status;
/* more irrelevant fields */
}
ProcessEntity : (этот объект представляет один шаг обработки для ExchangeEntity)
@Slf4j
@Entity
@Table(name = "T_PROCESS")
@Getter
@NoArgsConstructor
public class ProcessEntity {
@Id
@Type(type = "uuid-char")
@Column(name = "process_id", updatable = false)
private UUID id;
@Setter
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "fk_exchange_id")
private ExchangeEntity exchangeEntity;
@Setter
@NotBlank
@Column(name = "processor_status")
private String status;
@Setter
@Column(name = "consumed")
private Boolean consumed;
/* more irrelevant fields */
@PreConsumed
public void markAsConsumed(){
this.consumed = true;
}
}
Так я опрашиваю сущностей
[jpa://ProcessEntity?consumeDelete=false&consumer.namedQuery=notificationCompilerSelectQuery&consumer.transacted=false&entityType=com.foo.bar.entity.ProcessEntity&maximumResults=1&transactionManager=%23applicationTransactionManager]
Вот две конфигурации источника данных:
ApplicationDatasourceConfig (JPA)
@Configuration
@EnableJpaRepositories(basePackages = "foo.bar.repository.jpa",
entityManagerFactoryRef = "applicationEntityManagerFactory",
transactionManagerRef = "applicationTransactionManager")
@ConfigurationProperties(prefix = "spring.datasource.hikari")
@EnableTransactionManagement
public class ApplicationDatasourceConfig extends HikariConfig{
@Bean("applicationDatasource")
@Primary
public DataSource applicationDataSource(){
return new HikariDataSource(this);
}
@Bean("applicationDatasourceProperties")
@Primary
public DataSourceProperties dataSourceProperties(){
return new DataSourceProperties();
}
@Bean("applicationEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean applicationEntityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("applicationDatasource") DataSource dataSource){
return builder
.dataSource(dataSource)
.packages("foo.bar.entity")
.build();
}
@Bean("applicationTransactionManager")
@Primary
public PlatformTransactionManager applicationTransactionManager(@Qualifier("applicationEntityManagerFactory")EntityManagerFactory entityManagerFactory){
return new JpaTransactionManager(entityManagerFactory);
}
}
SecondaryDatasourceConfig (JDBC)
@Configuration
@ConfigurationProperties(prefix = "secondary.datasource")
@EnableTransactionManagement
public class SecondaryDatasourceConfig {
@Bean("secondaryDatasource")
public DataSource secondaryDataSource(){
return secondaryDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
public DataSourceProperties secondaryDataSourceProperties(){
return new DataSourceProperties();
}
@Bean("secondaryTransactionManager")
public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryDatasource") DataSource secondaryDataSource){
return new DataSourceTransactionManager(secondaryDataSource);
}
}
Итак, весь рабочий процесс выглядит следующим образом:
- Файл опроса CSV
- Создать ExchangeEntity и сохранить его со статусом = 'ОБРАБОТКА' в базе данных
- Создать ProcessEntity со ссылкой на это ExchangeEntity и status = 'foo' в базе данных
- END OF File2-Component-Route
- Маршрут 4711 опрашивает объект с namedQuery, соответствующим статусу = 'foo' (объект будет помечен как использованный в опросе)
- Маршрут 4711 создает свой собственный ProcessEntity со ссылкой на этот ExchangeEntity и статус = 'обработка' в базе данных
- Маршрут 4711 выполняет некоторые преобразования
- Маршрут 4711 обновляет статус ProcessEntity до status = 'bar'
- КОНЕЦ МАРШРУТА 4711
- Маршрут 4812 опрашивает объект с именем namedQuery, соответствующим статусу = 'bar' (объект будет помечен как использованный в опросе)
- Маршрут 4812 создает свой собственный ProcessEntity со ссылкой на этот ExchangeEntity и статус = 'обработка' в базе данных
- Маршрут 4812 выполняет некоторые преобразования
- Маршрут 4812 обновляет статус ProcessEntity до статуса = 'foo bar'
- КОНЕЦ МАРШРУТА 4812
- БОЛЬШЕ МАРШРУТОВ
- Обновление статуса ExchangeEntity до статуса = 'FINISHED', когда все маршруты завершены
Таким образом, по одному маршруту приложение обращается к вторичному источнику данных с помощью предопределенного оператора sql от другого разработчика, выполняемого экземпляром jdbcTemplate. Если запрос выдает исключение во время выполнения, это исключение перехватывается специальным обработчиком ошибок, зарегистрированным для этого маршрута. В этом случае приложение сделает следующее:
- Выполнить инструкцию SQL с jdbcTemplate на вторичном источнике данных (также oracle; только для чтения)
- ----> Исключение
- перехватывает Exception и выдает вместо него пользовательское исключение
- ErrorProcessor для маршрута вызывается
- Обновление статуса ProcessEntity, например status = 'sql_failure'
- Обновление статуса ExchangeEntity, например status = 'PROCESSING_ABORTED'
- Приложение закрывается
Вот так я обновляю статус ProcessEntity:
final ProcessEntity processEntity = getProcessEntity(exchange);
processEntity.setStatus(status);
processEntity.setEndDate(new Date());
processEntityRepository.save(processEntity);
Вот как я обновляю статус ExchangeEntity:
ExchangeEntity exchangeEntity = getExchangeEntity(exchange);
exchangeEntity.setStatus(ExchangeEntity.Status.PROCESSING_ABORTED);
exchangeEntity.setStatusDate(new Date());
Здесь мне не нужно явно вызывать хранилище, поскольку сущность будет обновлена после окончания маршрута.
Когда я намеренно указываю непонятную схему (в данном случае 'FOO') в выражении sql, я получаю следующее исключение:
at com.foo.bar.repository.jdbc.ImxJdbcRepository.findImxEmailRecipientsForAF(ImxJdbcRepository.java:79)
at com.foo.bar.repository.jdbc.ImxJdbcRepository$$FastClassBySpringCGLIB$$735660cf.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.foo.bar.repository.jdbc.ImxJdbcRepository$$EnhancerBySpringCGLIB$$aaf475c8.findImxEmailRecipientsForAF(<generated>)
at com.foo.bar.service.imx.EmailService.getAfRecipients(EmailService.java:58)
at com.foo.bar.component.notificationcompiler.processor.NotificationDataAggregator.getRecipients(NotificationDataAggregator.java:92)
at com.foo.bar.component.notificationcompiler.processor.NotificationDataAggregator.createNotificationModel(NotificationDataAggregator.java:116)
at com.foo.bar.component.notificationcompiler.processor.NotificationDataAggregator.process(NotificationDataAggregator.java:66)
at org.apache.camel.processor.DelegateSyncProcessor.process(DelegateSyncProcessor.java:63)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:541)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:198)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
at org.apache.camel.component.jpa.JpaConsumer.processBatch(JpaConsumer.java:196)
at org.apache.camel.component.jpa.JpaConsumer$1.doInTransaction(JpaConsumer.java:128)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:102)
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174)
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL "...." SQL state [90079]; error code [90079]; Schema "FOO" nicht gefunden
Schema "FOO" not found; SQL statement:
Schema "FOO" not found; SQL statement:
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:89)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1414)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:632)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:700)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:763)
at com.foo.bar.repository.jdbc.ImxJdbcRepository.findImxEmailRecipientsForAF(ImxJdbcRepository.java:76)
... 36 more
Caused by: org.h2.jdbc.JdbcSQLException: Schema "FOO" nicht gefunden
Schema "FOO" not found; SQL statement:
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.Parser.getSchema(Parser.java:701)
at org.h2.command.Parser.getSchema(Parser.java:707)
at org.h2.command.Parser.readTableFilter(Parser.java:1388)
at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:2138)
at org.h2.command.Parser.parseSelectSimple(Parser.java:2287)
at org.h2.command.Parser.parseSelectSub(Parser.java:2133)
at org.h2.command.Parser.parseSelectUnion(Parser.java:1946)
at org.h2.command.Parser.parseSelect(Parser.java:1919)
at org.h2.command.Parser.parsePrepared(Parser.java:463)
at org.h2.command.Parser.parse(Parser.java:335)
at org.h2.command.Parser.parse(Parser.java:307)
at org.h2.command.Parser.prepareCommand(Parser.java:278)
at org.h2.engine.Session.prepareLocal(Session.java:611)
at org.h2.engine.Session.prepareCommand(Session.java:549)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1247)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:76)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:304)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:311)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1527)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:615)
... 41 more
2019-04-05 16:05:58.704 WARN 12324 --- [//ProcessEntity] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1461, SQLState: 72000
2019-04-05 16:05:58.704 ERROR 12324 --- [//ProcessEntity] o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-01461: Ein LONG-Wert kann nur zur Einfügung in eine LONG-Spalte gebunden werden
2019-04-05 16:05:58.716 ERROR 12324 --- [//ProcessEntity] o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.GenericJDBCException: could not execute statement]
2019-04-05 16:05:58.752 WARN 12324 --- [//ProcessEntity] o.a.camel.component.jpa.JpaConsumer : Consumer Consumer[jpa://ProcessEntity?consumeDelete=false&consumer.namedQuery=notificationCompilerSelectQuery&consumer.transacted=false&entityType=com.foo.bar.entity.ProcessEntity&maximumResults=1&transactionManager=%23applicationTransactionManager] failed polling endpoint: jpa://ProcessEntity?consumeDelete=false&consumer.namedQuery=notificationCompilerSelectQuery&consumer.transacted=false&entityType=com.foo.bar.entity.ProcessEntity&maximumResults=1&transactionManager=%23applicationTransactionManager. Will try again at next poll. Caused by: [javax.persistence.PersistenceException - org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement]
javax.persistence.PersistenceException: org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
at org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:160) ~[camel-jpa-2.19.0.jar:2.19.0]
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) [camel-core-2.19.0.jar:2.19.0]
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) [camel-core-2.19.0.jar:2.19.0]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_191]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_191]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_191]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]
Caused by: org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:351) ~[spring-orm-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:253) ~[spring-orm-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:536) ~[spring-orm-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746) ~[spring-tx-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714) ~[spring-tx-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:152) ~[spring-tx-5.1.2.RELEASE.jar:5.1.2.RELEASE]
at org.apache.camel.component.jpa.JpaConsumer.poll(JpaConsumer.java:102) ~[camel-jpa-2.19.0.jar:2.19.0]
... 9 common frames omitted
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:178) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3171) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3686) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:90) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:511) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3283) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2479) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:178) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:39) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:271) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:98) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:532) ~[spring-orm-5.1.2.RELEASE.jar:5.1.2.RELEASE]
... 13 common frames omitted
Caused by: java.sql.SQLException: ORA-01461: Ein LONG-Wert kann nur zur Einfügung in eine LONG-Spalte gebunden werden
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3665) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1352) ~[ojdbc6-11.2.0.3.jar:11.2.0.3.0]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-3.2.0.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-3.2.0.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
... 30 common frames omitted
Кроме того, обходной путь для обработки исключений, как описано выше (обновление статусов), НЕ работает. Каким-то образом JPA не может зафиксировать транзакцию , хотя исключение произошло в другом источнике данных
Я уже пытался аннотировать соответствующие методы с помощью @Transaction (noRollbackFor = Exception.class), но это не решает проблему.
Я должен также упомянуть, что это происходит ТОЛЬКО с Oracle - когда я использую базу данных H2 In Memory во время локальной разработки / тестирования, все работает нормально, и рабочий процесс с ошибками выполняется правильно.
У кого-нибудь есть идея? Буду очень признателен за любые полезные комментарии!
Заранее спасибо.