From e18f13a12a0b4d9762ea8dce3445a8c53110c138 Mon Sep 17 00:00:00 2001 From: uzma Date: Mon, 1 May 2023 22:57:57 +0100 Subject: [PATCH] [BAEL-6105] code for correct use of flush --- .../java/com/baeldung/flush/AppConfig.java | 57 +++++ .../java/com/baeldung/flush/Customer.java | 36 +++ .../com/baeldung/flush/CustomerAddress.java | 47 ++++ .../boot/flush/FlushIntegrationTest.java | 205 ++++++++++++++++++ 4 files changed, 345 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/AppConfig.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/Customer.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/CustomerAddress.java create mode 100644 persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/flush/FlushIntegrationTest.java diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/AppConfig.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/AppConfig.java new file mode 100644 index 0000000000..333dc4a956 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/AppConfig.java @@ -0,0 +1,57 @@ +package com.baeldung.flush; + +import java.util.Properties; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; + +@Configuration +public class AppConfig { + + @Bean + public EntityManager entityManager(EntityManagerFactory entityManagerFactory) { + + return entityManagerFactory.createEntityManager(); + } + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) + .build(); + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(dataSource); + emf.setPackagesToScan("com.baeldung.flush"); + emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + emf.setJpaProperties(getHibernateProperties()); + return emf; + } + + @Bean + public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory.getObject()); + } + + private Properties getHibernateProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "create"); + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + return properties; + } +} + + + + diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/Customer.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/Customer.java new file mode 100644 index 0000000000..786762cbeb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/Customer.java @@ -0,0 +1,36 @@ +package com.baeldung.flush; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Customer { + + private String name; + private int age; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } +} diff --git a/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/CustomerAddress.java b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/CustomerAddress.java new file mode 100644 index 0000000000..8e4953117a --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/main/java/com/baeldung/flush/CustomerAddress.java @@ -0,0 +1,47 @@ +package com.baeldung.flush; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class CustomerAddress { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String street; + + private String city; + + private long customer_id; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public Long getId() { + return id; + } + + public long getCustomer_id() { + return customer_id; + } + + public void setCustomer_id(long customer_id) { + this.customer_id = customer_id; + } +} diff --git a/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/flush/FlushIntegrationTest.java b/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/flush/FlushIntegrationTest.java new file mode 100644 index 0000000000..a134fe95d9 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-3/src/test/java/com/baeldung/boot/flush/FlushIntegrationTest.java @@ -0,0 +1,205 @@ +package com.baeldung.boot.flush; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityTransaction; +import javax.persistence.FlushModeType; +import javax.persistence.TypedQuery; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.flush.AppConfig; +import com.baeldung.flush.Customer; +import com.baeldung.flush.CustomerAddress; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { AppConfig.class }) + +public class FlushIntegrationTest { + + @Autowired + private EntityManager entityManager; + + @Test + void givenANewCustomer_whenPersistAndNoFlush_thenDatabaseNotSynchronizedWithPersistentContextUsingCommitFlushMode() { + + entityManager.setFlushMode(FlushModeType.COMMIT); + + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + Customer customer = new Customer(); + customer.setName("Alice"); + customer.setAge(30); + entityManager.persist(customer); + Customer customerInContext = entityManager.find(Customer.class, customer.getId()); + assertThat(customerInContext).isNotNull(); + assertThat(customerInContext.getName()).isEqualTo("Alice"); + + TypedQuery retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class); + + List resultList = retrievedCustomer.getResultList(); + + assertThat(resultList).isEmpty(); + transaction.rollback(); + } + + @Test + void givenANewCustomer_whenPersistAndFlush_thenDatabaseSynchronizedWithPersistentContextUsingCommitFlushMode() { + entityManager.setFlushMode(FlushModeType.COMMIT); + + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + Customer customer = new Customer(); + customer.setName("Alice"); + customer.setAge(30); + entityManager.persist(customer); + entityManager.flush(); + Long generatedCustomerID = customer.getId(); + Customer customerInContext = entityManager.find(Customer.class, generatedCustomerID); + assertThat(customerInContext).isNotNull(); + assertThat(customerInContext.getName()).isEqualTo("Alice"); + + TypedQuery retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class); + + List resultList = retrievedCustomer.getResultList(); + + assertThat(resultList).isNotEmpty(); + assertThat(resultList.get(0) + .getName()).isEqualTo("Alice"); + assertThat(resultList.get(0) + .getAge()).isEqualTo(30); + assertThat(resultList.get(0) + .getId()).isEqualTo(generatedCustomerID); + transaction.rollback(); + } + + @Test + void givenANewCustomer_whenPersistAndNoFlush_thenDBIsSyncronizedWithThePersistentContextWithAutoFlushMode() { + entityManager.setFlushMode(FlushModeType.AUTO); + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + Customer customer = new Customer(); + customer.setName("Alice"); + customer.setAge(30); + entityManager.persist(customer); + Customer customerInContext = entityManager.find(Customer.class, customer.getId()); + assertThat(customerInContext).isNotNull(); + assertThat(customerInContext.getName()).isEqualTo("Alice"); + + TypedQuery retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class); + + List resultList = retrievedCustomer.getResultList(); + + assertThat(resultList).isNotEmpty(); + assertThat(resultList.get(0) + .getAge()).isEqualTo(30); + assertThat(resultList.get(0) + .getName()).isEqualTo("Alice"); + assertThat(resultList.get(0) + .getId()).isEqualTo(customer.getId()); + transaction.rollback(); + } + + @Test + public void givenANewCustomer_whenPersistAndFlush_thenCustomerIdGeneratedToBeAddedInAddress() { + entityManager.setFlushMode(FlushModeType.COMMIT); + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + + Customer customer = new Customer(); + customer.setName("John"); + customer.setAge(25); + entityManager.persist(customer); + entityManager.flush(); + + Customer singleResult = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class) + .getSingleResult(); + Long customerId = singleResult.getId(); + + CustomerAddress address = new CustomerAddress(); + address.setCustomer_id(customerId); + entityManager.persist(address); + entityManager.flush(); + + CustomerAddress customerAddress = entityManager.createQuery("SELECT a FROM CustomerAddress a WHERE a.customer_id = :customerID", CustomerAddress.class) + .setParameter("customerID", customerId) + .getSingleResult(); + + Assertions.assertThat(customerAddress) + .isNotNull(); + + transaction.rollback(); + } + + @Test + public void givenFlushModeAutoAndNewCustomer_whenPersistAndNoFlush_thenCustomerIdGeneratedToBeAddedInAddress() { + entityManager.setFlushMode(FlushModeType.AUTO); + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + + Customer customer = new Customer(); + customer.setName("John"); + customer.setAge(25); + entityManager.persist(customer); + + Customer singleResult = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class) + .getSingleResult(); + Long customerId = singleResult.getId(); + + CustomerAddress address = new CustomerAddress(); + address.setCustomer_id(customerId); + entityManager.persist(address); + + CustomerAddress customerAddress = entityManager.createQuery("SELECT a FROM CustomerAddress a WHERE a.customer_id = :customerID", CustomerAddress.class) + .setParameter("customerID", customerId) + .getSingleResult(); + + Assertions.assertThat(customerAddress) + .isNotNull(); + + transaction.rollback(); + } + + @Test + public void givenFlushModeCommitAndNewCustomer_whenPersistAndNoFlush_thenCustomerIdGeneratedToBeAddedInAddress() { + entityManager.setFlushMode(FlushModeType.AUTO); + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + + Customer customer = new Customer(); + customer.setName("John"); + customer.setAge(25); + entityManager.persist(customer); + + Customer singleResult = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class) + .getSingleResult(); + Long customerId = singleResult.getId(); + + CustomerAddress address = new CustomerAddress(); + address.setCustomer_id(customerId); + entityManager.persist(address); + + CustomerAddress customerAddress = entityManager.createQuery("SELECT a FROM CustomerAddress a WHERE a.customer_id = :customerID", CustomerAddress.class) + .setParameter("customerID", customerId) + .getSingleResult(); + + Assertions.assertThat(customerAddress) + .isNotNull(); + + transaction.rollback(); + } + + @AfterEach + public void cleanup() { + entityManager.clear(); + } +}