Spring - No Entitymanager with Actual Transaction Available for Current Thread - Cannot Reliably Process 'Persist' Call

Spring - No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

I had the same problem and I annotated the method as @Transactional and it worked.

UPDATE: checking the spring documentation it looks like by default the PersistenceContext is of type Transaction, so that's why the method has to be transactional (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html):

The @PersistenceContext annotation has an optional attribute type,
which defaults to PersistenceContextType.TRANSACTION. This default is
what you need to receive a shared EntityManager proxy. The
alternative, PersistenceContextType.EXTENDED, is a completely
different affair: This results in a so-called extended EntityManager,
which is not thread-safe and hence must not be used in a concurrently
accessed component such as a Spring-managed singleton bean. Extended
EntityManagers are only supposed to be used in stateful components
that, for example, reside in a session, with the lifecycle of the
EntityManager not tied to a current transaction but rather being
completely up to the application.

spring + jpa+hibernate = No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

Spring use Spring AOP (Aspect Oriented Programming) to implement transaction which means you must use public access level on your MyTest2() method so it can be intercepted by AOP proxy. Otherwise it is like you never annotate your method with @Transactional

No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

thank you @mechkov for your time and help,
My problem is resolved by changing my configuration file, so I have used a Configuration Class with annotations and its works so fine, I still Don't know where the problem was

    @Configuration
@ComponentScan(basePackages = "your package")
@EnableTransactionManagement
public class DatabaseConfig {

protected static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver";
protected static final String PROPERTY_NAME_DATABASE_PASSWORD = "password";
protected static final String PROPERTY_NAME_DATABASE_URL = "jdbc:mysql://localhost:3306/databasename";
protected static final String PROPERTY_NAME_DATABASE_USERNAME = "login";

private static final String PROPERTY_PACKAGES_TO_SCAN = "where your models are";
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
entityManagerFactoryBean.setPackagesToScan(PROPERTY_PACKAGES_TO_SCAN);
return entityManagerFactoryBean;
}

@Bean
public BasicDataSource dataSource(){
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(PROPERTY_NAME_DATABASE_DRIVER);
ds.setUrl(PROPERTY_NAME_DATABASE_URL);
ds.setUsername(PROPERTY_NAME_DATABASE_USERNAME);
ds.setPassword(PROPERTY_NAME_DATABASE_PASSWORD);
ds.setInitialSize(5);
return ds;
}

@Bean
public JpaVendorAdapter jpaVendorAdapter(){
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setShowSql(true);
adapter.setGenerateDdl(true);

//I'm using MySQL5InnoDBDialect to make my tables support foreign keys
adapter.setDatabasePlatform("org.hibernate.dialect.MySQL5InnoDBDialect");
return adapter;
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}

}


Related Topics



Leave a reply



Submit