1

in my project, I am using both JPA and spring-jdbc-template & NamedParameterTemplate. I need to get transaction support for both.

So how to configure @Transactional for both JPA & spring-JDBC ?

Here are the 2 classes I used for configuring those.

Class number 1: PersistenceConfiguration This is the class that declares transaction-management should be enabled.

            @Configuration
        @EnableTransactionManagement
        @EnableJpaRepositories(basePackages = {"com.google.product.repository"},
                excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.google.product.repository.mongoRepository.*.*Repository"))
        public class PersistenceConfiguration {

            @Autowired
            private DataSource dataSource;

            @Autowired
            private Properties entityManagerProperties;

            @Bean
            public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
                final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
                em.setDataSource(dataSource);
                em.setPackagesToScan("com.google.product.model");
                final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
                em.setJpaVendorAdapter(vendorAdapter);
                em.setJpaProperties(entityManagerProperties);
                return em;
            }

        }

Class number 2: ProdDatabaseConfiguration This is the class that declares beans releted toJDBC & JPA. for example primaryJdbcTemplate ,secondaryJdbcTemplate & entityManagerProperties.

@Configuration
    @PropertySource({"classpath:database-prod.properties"})
    @Profile("prod")
    public class ProdDatabaseConfiguration {

        private static final Logger LOG = LoggerFactory.getLogger(ProdDatabaseConfiguration.class);


        @Value("${jdbc.jndiName}")
        private String jndiName;


        @Value("${hibernate.dialect}")
        private String hibernateDialect;

        @Value("${hibernate.show_sql}")
        private String hibernateShowSql;

        @Value("${hibernate.cache.use_second_level_cache}")
        private String hibernateSecondLevelCache;

        @Value("${hibernate.cache.use_query_cache}")
        private String hibernateQueryCache;

        @Value("${jadira.usertype.databaseZone}")
        private String databaseZone;

        @Value("${jadira.usertype.javaZone}")
        private String javaZone;

        @Value("${mongo.jndiName}")
        private String mongoJndiName;

        @Bean
        public DataSource dataSource() {
            JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
            return jndiDataSourceLookup.getDataSource(jndiName);
        }

        @Bean(name = "entityManagerProperties")
        public Properties additionalProperties() {
            final Properties hibernateProperties = new Properties();
            hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "none");
            hibernateProperties.setProperty("hibernate.dialect", hibernateDialect);
            hibernateProperties.setProperty("hibernate.show_sql", hibernateShowSql);
            hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", hibernateSecondLevelCache);
            hibernateProperties.setProperty("hibernate.cache.use_query_cache", hibernateQueryCache);
            hibernateProperties.setProperty("jadira.usertype.databaseZone", databaseZone);
            hibernateProperties.setProperty("jadira.usertype.javaZone", javaZone);
            return hibernateProperties;
        }

        @Bean(name = "primaryJdbcTemplate")
        public JdbcTemplate primaryJdbcTemplate() {
            JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
            return new JdbcTemplate(jndiDataSourceLookup.getDataSource(jndiName));
        }

        @Bean(name = "secondaryJdbcTemplate")
        public NamedParameterJdbcTemplate secondaryJdbcTemplate() {
            JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
            return new NamedParameterJdbcTemplate(jndiDataSourceLookup.getDataSource(jndiName));
        }
Sanka
  • 1,294
  • 1
  • 11
  • 20
  • https://stackoverflow.com/questions/33594625/java-configuration-for-jdbctemplate-and-transaction-management-in-spring – Sanka Jun 18 '19 at 19:03
  • Why don't you use Spring Boot autoconfiguration? – Simon Martinelli Jun 18 '19 at 19:11
  • @SimonMartinelli will it work? existing code already has gone live.secondaryJdbcTemplate newly introduced by me for this CR. So I want to do this with minimal changes – Sanka Jun 19 '19 at 04:02
  • Do you have one or two datasources – Simon Martinelli Jun 19 '19 at 06:01
  • @SimonMartinelli only one – Sanka Jun 19 '19 at 08:27
  • Remove your configuration, put the datasource config in `application.properties` and it will work. The `JpaTransactionManager` is perfectly capably of handling plain JDBC transactions next to JPA transactions. – M. Deinum Jun 19 '19 at 08:39
  • @M.Deinum will Spring-JDBCTemplete support? – Sanka Jun 19 '19 at 09:56
  • Not sure what to make of that comment. Spring Boot automatically configures a `JdbcTemplate` and `NamedJdbcTemplate`. – M. Deinum Jun 19 '19 at 10:06
  • got your point. thanks. – Sanka Jun 19 '19 at 10:15
  • This question is about the Spring Boot configuration. If you are interested more in Spring without Spring Boot (or how Spring Boot configures the `TransactionManager` under the hood this question might help: https://stackoverflow.com/questions/2673678/what-transaction-manager-should-i-use-for-jbdc-template-when-using-jpa – Jens Schauder Jun 18 '20 at 14:38

1 Answers1

2

Because you are only using one datasource you can remove all the configuration and just use the spring.datasource properties.

Transaction will also work out of the box because you will have only this datasource.

Read more about this topic in the official documentation:

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-sql

Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82