Spring定时任务无法存储JPA实体且无异常排查求助
Spring定时任务中JPA实体存储异常问题
- 通过REST接口调用代码时,实体可正常存入Oracle数据库;但定时调度执行自动化逻辑时,实体无法存储,即使删除数据库表也无任何异常抛出。
- 将Service中的
myEntityRepository.save(myEntity)改为myEntityRepository.saveAndFlush(myEntity)后,日志显示已创建事务,却抛出“无事务进行中”的异常。 - 改用Oracle序列生成ID时,能正常获取序列ID,但依然没有表不存在的提示;若序列不存在则会正常抛出异常。
实体类(UUID生成ID)
import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @Entity @Table(name = "MY_ENTITY") @Getter @Setter public class MyEntity { @Id @Column(name = "ident") @GeneratedValue(generator = "uuid-hibernate-generator") @GenericGenerator(name = "uuid-hibernate-generator", strategy = "org.hibernate.id.UUIDGenerator") private String ident; @Column(name = "content") private String content; }
Repository
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @Repository @Transactional public interface MyEntityRepository extends JpaRepository<MyEntity, String> { }
Service类
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service @Slf4j public class TestService { @Autowired private MyEntityRepository myEntityRepository; @Transactional(propagation = Propagation.REQUIRES_NEW) public void storeMyEntity(){ try { MyEntity myEntity = new MyEntity(); myEntity.setContent("ABC"); myEntityRepository.save(myEntity); } catch (Exception ex){ log.error("Error", ex); } } }
定时任务类
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Slf4j @Component public class TestJob { @Autowired private TestService testService; @Scheduled(fixedRateString = "10000") public void testJob() { log.info("store DB entity in job - started"); testService.storeMyEntity(); log.info("store DB entity in job - finished"); } }
数据源配置
@Bean public DataSource myDataSource() throws SQLException { HikariConfig config = new HikariConfig(); config.setJdbcUrl(url); config.setUsername(username); config.setPassword(password); config.setConnectionTimeout(connectionTimeoutMillis); config.setMaximumPoolSize(maximumPoolSize); return new HikariDataSource(config); } @Bean(name = "transactionManager") public DataSourceTransactionManager transactionManager(DataSource myDataSource) { return new DataSourceTransactionManager(myDataSource); }
正常执行(save方法)日志
11:38:29.851 [scheduling-1] INFO playground.TestJob - store DB entity in job - started 11:38:29.851 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [playground.TestService.storeMyEntity]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT 11:38:29.855 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1783732892 wrapping oracle.jdbc.driver.T4CConnection@16a5eb6d] for JDBC transaction 11:38:29.855 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1783732892 wrapping oracle.jdbc.driver.T4CConnection@16a5eb6d] to manual commit 11:38:29.855 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Participating in existing transaction 11:38:29.855 [scheduling-1] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Opening JPA EntityManager 11:38:29.855 [scheduling-1] DEBUG o.h.e.i.AbstractSaveEventListener - Generated identifier: 0e68b146-0092-4fd1-98e3-2403a915196e, using strategy: org.hibernate.id.UUIDGenerator 11:38:29.855 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction commit 11:38:29.855 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Committing JDBC transaction on Connection [HikariProxyConnection@1783732892 wrapping oracle.jdbc.driver.T4CConnection@16a5eb6d] 11:38:29.858 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1783732892 wrapping oracle.jdbc.driver.T4CConnection@16a5eb6d] after transaction 11:38:29.858 [scheduling-1] INFO c.c.r.m.reporting.playground.TestJob - store DB entity in job - finished
saveAndFlush方法异常日志
11:44:18.181 [scheduling-1] INFO c.c.r.m.reporting.playground.TestJob - store DB entity in job - started 11:44:18.181 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [playground.TestService.storeMyEntity]: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT 11:44:18.184 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1365602219 wrapping oracle.jdbc.driver.T4CConnection@53c1179a] for JDBC transaction 11:44:18.185 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1365602219 wrapping oracle.jdbc.driver.T4CConnection@53c1179a] to manual commit 11:44:18.185 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Participating in existing transaction 11:44:18.185 [scheduling-1] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Opening JPA EntityManager 11:44:18.185 [scheduling-1] DEBUG o.h.e.i.AbstractSaveEventListener - Generated identifier: 2a056d01-636f-48ca-a595-3e164a3110ac, using strategy: org.hibernate.id.UUIDGenerator 11:44:18.185 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Participating transaction failed - marking existing transaction as rollback-only 11:44:18.185 [scheduling-1] DEBUG o.s.j.d.DataSourceTransactionManager - Setting JDBC transaction [HikariProxyConnection@1365602219 wrapping oracle.jdbc.driver.T4CConnection@53c1179a] rollback-only 11:44:18.185 [scheduling-1] ERROR c.c.r.m.r.playground.TestService - Error org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
改用Oracle序列生成ID的实体类
@Entity @Table(name = "MY_ENTITY") @Getter @Setter public class MyEntity { @Id @GeneratedValue(generator="seqGen") @SequenceGenerator(name="seqGen",sequenceName="my_entity_seq", allocationSize=1) private Long id; @Column(name = "content") private String content; }
现象说明:此时调用save()能获取Oracle序列ID,但仍无表不存在的提示;若序列不存在则会正常抛出异常。
内容的提问来源于stack exchange,提问作者user1604064
相关产品推荐
相关产品推荐

