0

My project includes the combination of Spring Boot + Hibernate + Postgresql. Since the project started I thought adding @Transactional to the method will automatically triggered a rollback when a RunTimeException is thrown, but it seems that I was wrong. Here's the the application properties.

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.properties.hibernate.default_schema=sbs

# HIKARI CONNECTION POOL
spring.datasource.hikari.pool-name=SBS_Datasource
#spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=3
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.idle-timeout=10000
spring.datasource.hikari.max-lifetime=600000
spring.datasource.hikari.connection-test-query=select 1
spring.datasource.hikari.connection-init-sql=select 1
spring.datasource.hikari.isolate-internal-queries=true
spring.datasource.hikari.allow-pool-suspension=true
spring.datasource.hikari.register-mbeans=true

As you can see, the auto-commit has been disabled, dialect is set to PostgreSQLDialect and we're using hikari pool.

The situation is: this happens at start-up phase of the application. We want to load data from csv and persist into the database when the application is starting up. Here are the components:

@ConditionalOnProperty(
        value = "sbs.api.master-data.enable-loader",
        havingValue = "true"
)
@Slf4j
public class MasterDataLoader {
   ...
    @PostConstruct
    public void loadMasterData() {
        log.info("***MasterDataLoader STARTS");
        this.loadCountryCodes();
        this.loadZipCities();
        log.info("***MasterDataLoader ENDS");
    }

    private void loadCountryCodes() {
        log.info("***Loading country codes from {}", this.countryCodeFilePath);
        try {
            List<CSVCountry> csvCountries = this.countryLoader.read(countryCodeFilePath);
            this.countryLoader.save(csvCountries);
            log.info("*** length " + csvCountries.size());
        } catch (Exception e) {
            log.warn("Exception while loading country code {}", e);
        }
    }
   ...
}

Code that has @Transaction inside countryLoadder

...
    @Transactional
    void save(List<CSVCountry> csvCountries) {
        dossierRepository.save(new DossierEntity());
        throw new NullPointerException();
    }
}
...

The actual code is more complex than this but since I saw it didn't work so I decided to go with the simplest possible example.

I expected the created dossier would be removed because of @Transactional, but it wasn't.

Please help to tell what's wrong with the code or there is a problem with the technology stack (Spring + Hikari + PostgreSQL).

SOLUTION:

Loc Truong
  • 359
  • 5
  • 22
  • The method should be `public` yours has default accesibility. Next to that it is an internal method call which won't work. Spring uses proxies to apply AOP, that only works for method callls INTO the object, not for methods calls INSIDE the object. Finally you are calling a method from within an `@PostConstruct` annotated method, this method could execute before a transactional proxy has been created, leading to no transactions. – M. Deinum Jan 30 '20 at 09:51
  • Why does access modifier affect the @Transactional? – Loc Truong Jan 30 '20 at 09:57
  • Found it, thanks @M.Deinum https://stackoverflow.com/questions/17346679/transactional-on-postconstruct-method – Loc Truong Jan 30 '20 at 10:03
  • Does this answer your question? [@Transactional on @PostConstruct method](https://stackoverflow.com/questions/17346679/transactional-on-postconstruct-method) – lugiorgi Jan 30 '20 at 10:04
  • It is due to this https://stackoverflow.com/questions/17346679/transactional-on-postconstruct-method It costs me 2 hours to trace. – Loc Truong Jan 30 '20 at 10:05
  • thanks @lugiorgi, I found it myself though :D – Loc Truong Jan 30 '20 at 10:08
  • sorry, you were too fast ;) – lugiorgi Jan 30 '20 at 10:08

0 Answers0