Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JpaRepository: No Transaction in progress

I'm using Spring Data Jpa along with hibernate. I have a repository that extends JpaRepository and I'm using it to save records to the database. But when I call .flush(), the following error occurs.

I've seen other questions with a similar error but after trying to use @Transaction in the repository as well, I get the same error.

Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1171)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1332)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
    at com.sun.proxy.$Proxy64.flush(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:262)
    at com.sun.proxy.$Proxy64.flush(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.flush(SimpleJpaRepository.java:397)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:365)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    ... 75 more

The Repository

@Repository
@Transactional
public interface AttributeRepository extends JpaRepository<Attribute, Long> {
    Attribute findById(long id);
}

My config contains the entity manager factory and the platform transaction manager that JPA requires,

@Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(BoneCPDataSource ds) throws IOException {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(ds);
        em.setPackagesToScan(new String[] { "org.scripps.branch.entity" });
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        em.setJpaProperties(additionalProperties());
        return em;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    @Bean
    public PlatformTransactionManager transactionManager(
            EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

The Service where the saveandFlush() method is called,

@Service
public interface FeatureService {

    @Transactional
    public List<Feature> rankFeatures(Instances data, List<String> entrezIds, Dataset d);
}

Just to add, I'm injecting the repository using @Autowired into the implementation of the service.

like image 933
Karthik Avatar asked Sep 30 '22 01:09

Karthik


2 Answers

I think you forgot to enable Jpa Transaction or to associate Spring Data with the transaction manager:

Ex enable transaction management:

@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)

Ex associate transaction manager with Jpa Repositories:

@EnableJpaRepositories(transactionManagerRef="transactionManager", 
    entityManagerFactoryRef="entityManagerFactory", 
    value="com.repositories.pkg.location" )
like image 67
kauedb Avatar answered Oct 06 '22 01:10

kauedb


Annotating your repository with @Transactional won't help; you have to annotate the service method with @Transactional. "service method" meaning the method encapsulating both, the call into the save method of the repo and the flush call.

like image 23
Hille Avatar answered Oct 06 '22 00:10

Hille