title: Spring Boot Hibernate Postgresql @Transactional does not rollback
body: <p>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.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>As you can see, the <code>auto-commit</code> has been disabled, dialect is set to <code>PostgreSQLDialect</code> and we're using hikari pool.</p>
  
  <p>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:</p>
  
  <pre><code>@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&lt;CSVCountry&gt; 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></pre>
  
  <p>Code that has @Transaction inside <code>countryLoadder</code></p>
  
  <pre><code>...
      @Transactional
      void save(List&lt;CSVCountry&gt; csvCountries) {
          dossierRepository.save(new DossierEntity());
          throw new NullPointerException();
      }
  }
  ...
  </code></pre>
  
  <p>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.</p>
  
  <p>I expected the created dossier would be removed because of @Transactional, but it wasn't.</p>
  
  <p>Please help to tell what's wrong with the code or there is a problem with the technology stack (Spring + Hikari + PostgreSQL).</p>
  
  <p><strong>SOLUTION:</strong></p>
  
  <ul>
  <li>Check this out: <a href="https://stackoverflow.com/questions/17346679/transactional-on-postconstruct-method">@Transactional on @PostConstruct method</a> </li>
  </ul>