简体   繁体   中英

Spring Boot - Persist transaction directly to embedded database

I use Spring Boot Jpa in a standalone GUI (Swing) java application with an embedded H2 database.

I use Spring Boot 1.3.0 and this is my additional configuration:

  private static final String dataSourceUrl = "jdbc:h2:./databse;DB_CLOSE_ON_EXIT=FALSE";
  @Bean
  public DataSource dataSource() {
      return DataSourceBuilder.create().url(dataSourceUrl).username("user").password("pwd").build();
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
      LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource);
      em.setPackagesToScan(new String[] { "packages.to.scan" });

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);

      Properties properties = new Properties();
      properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
      properties.setProperty("hibernate.hbm2ddl.auto", "update");
      em.setJpaProperties(properties);

      return em;
  }

In my application.properties file I have only one line: spring.aop.proxy-target-class=true .

For my repositories I extend JpaRepository .

Everything is working, the only problem I had recently: On a MAC which was running the application the MAC had some kind of problems and crashed. Afterwards none of the modification which was done before was actually stored in the database. I use the @Transactional annotation to modify data in the database.

I'm not very experienced with databases but after googling around I guess the transactions are cached by the persistence context (not sure if the terminology is correct) and is actually persisted when the application is closed. I checked the database file and made some manipluation through the GUI (includes also some queries) but the modification date of the database file changed only when I closed the application.

As this is a standalone GUI application there will be no performance issues if every transaction will be directly perisisted in the database. Am I on the correct way and how could I achieve that every transaction is directly persisted in the database? Are there any configuration I have to do or do I have to add any code after every call of the save() method of a repository?

If not, I have absolutely no idea how to debug this kind of problems as I have to admit that I'm not pretty sure whats actually going on under the hood..

Hibernate decides on it's own when to write to database (flushing the persistence context) based on optimization parameters and configured flushing strategy.

Maybe you can take a look here and adjust the behavior according to your needs:

https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch03.html

Information about the flush modes will also help you:

http://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/FlushMode.html

Springs @Transactional follows the container managed transaction paradigm. By default if one @Transactional invokes a @Transactional method in another Componet/service/repository the transaction is propagated. When the outermost @Transactional method completes the transaction will be committed to the database.

JPA may flush data to the database multiple time within the same transaction, but everything in the transaction is either committed or rolled back when the transaction completed. If you have @Transactional on a @Controller, the transaction completes after the DispatchServlet has called the handler method (More specifically it happens indside the GCLIB or JDK Proxy which is created using Spring AOP)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM