[BAEL-6105] code for correct use of flush
This commit is contained in:
parent
5843ca5422
commit
4a479efd69
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.flush;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
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 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.flush;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Customer {
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (o == null || getClass() != o.getClass())
|
||||||
|
return false;
|
||||||
|
Customer customer = (Customer) o;
|
||||||
|
return age == customer.age && name.equals(customer.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.flush;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
package com.baeldung.spring.data.jpa.flush;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.EntityManagerFactory;
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
import jakarta.persistence.FlushModeType;
|
||||||
|
import jakarta.persistence.PersistenceUnit;
|
||||||
|
import jakarta.persistence.TypedQuery;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@ContextConfiguration(classes = { AppConfig.class })
|
||||||
|
public class FlushIntegrationTest {
|
||||||
|
|
||||||
|
private static final Customer EXPECTED_CUSTOMER = aCustomer();
|
||||||
|
|
||||||
|
@PersistenceUnit
|
||||||
|
private EntityManagerFactory entityManagerFactory;
|
||||||
|
|
||||||
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
entityManager = entityManagerFactory.createEntityManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenANewCustomer_whenPersistAndNoFlush_thenDatabaseNotSynchronizedWithPersistentContextUsingCommitFlushMode() {
|
||||||
|
|
||||||
|
entityManager.setFlushMode(FlushModeType.COMMIT);
|
||||||
|
|
||||||
|
EntityTransaction transaction = getTransaction();
|
||||||
|
Customer customer = saveCustomerInPersistentContext("Alice", 30);
|
||||||
|
Customer customerInContext = entityManager.find(Customer.class, customer.getId());
|
||||||
|
assertDataInPersitentContext(customerInContext);
|
||||||
|
|
||||||
|
TypedQuery<Customer> retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class);
|
||||||
|
|
||||||
|
List<Customer> resultList = retrievedCustomer.getResultList();
|
||||||
|
|
||||||
|
assertThat(resultList).isEmpty();
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenANewCustomer_whenPersistAndFlush_thenDatabaseSynchronizedWithPersistentContextUsingCommitFlushMode() {
|
||||||
|
entityManager.setFlushMode(FlushModeType.COMMIT);
|
||||||
|
|
||||||
|
EntityTransaction transaction = getTransaction();
|
||||||
|
Customer customer = saveCustomerInPersistentContext("Alice", 30);
|
||||||
|
entityManager.flush();
|
||||||
|
Long generatedCustomerID = customer.getId();
|
||||||
|
|
||||||
|
Customer customerInContext = entityManager.find(Customer.class, generatedCustomerID);
|
||||||
|
assertDataInPersitentContext(customerInContext);
|
||||||
|
|
||||||
|
TypedQuery<Customer> retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class);
|
||||||
|
|
||||||
|
Customer result = retrievedCustomer.getSingleResult();
|
||||||
|
assertThat(result).isEqualTo(EXPECTED_CUSTOMER);
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenANewCustomer_whenPersistAndFlush_thenCustomerIdGeneratedToBeAddedInAddress() {
|
||||||
|
entityManager.setFlushMode(FlushModeType.COMMIT);
|
||||||
|
EntityTransaction transaction = getTransaction();
|
||||||
|
|
||||||
|
saveCustomerInPersistentContext("John", 25);
|
||||||
|
entityManager.flush();
|
||||||
|
|
||||||
|
Customer retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'John'", Customer.class)
|
||||||
|
.getSingleResult();
|
||||||
|
Long customerId = retrievedCustomer.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();
|
||||||
|
|
||||||
|
assertThat(customerAddress).isNotNull();
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenANewCustomer_whenPersistAndNoFlush_thenDBIsSynchronizedWithThePersistentContextWithAutoFlushMode() {
|
||||||
|
entityManager.setFlushMode(FlushModeType.AUTO);
|
||||||
|
EntityTransaction transaction = getTransaction();
|
||||||
|
|
||||||
|
Customer customer = saveCustomerInPersistentContext("Alice", 30);
|
||||||
|
Customer customerInContext = entityManager.find(Customer.class, customer.getId());
|
||||||
|
assertDataInPersitentContext(customerInContext);
|
||||||
|
|
||||||
|
TypedQuery<Customer> retrievedCustomer = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name = 'Alice'", Customer.class);
|
||||||
|
|
||||||
|
Customer result = retrievedCustomer.getSingleResult();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo(EXPECTED_CUSTOMER);
|
||||||
|
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFlushModeAutoAndNewCustomer_whenPersistAndNoFlush_thenCustomerIdGeneratedToBeAddedInAddress() {
|
||||||
|
entityManager.setFlushMode(FlushModeType.AUTO);
|
||||||
|
EntityTransaction transaction = getTransaction();
|
||||||
|
|
||||||
|
saveCustomerInPersistentContext("John", 25);
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
assertThat(customerAddress).isNotNull();
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFlushModeAutoAndNewCustomer_whenPersistAndFlush_thenCustomerIdGeneratedToBeAddedInAddress() {
|
||||||
|
entityManager.setFlushMode(FlushModeType.AUTO);
|
||||||
|
EntityTransaction transaction = getTransaction();
|
||||||
|
|
||||||
|
saveCustomerInPersistentContext("John", 25);
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
assertThat(customerAddress).isNotNull();
|
||||||
|
|
||||||
|
transaction.rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertDataInPersitentContext(Customer customerInContext) {
|
||||||
|
assertThat(customerInContext).isNotNull();
|
||||||
|
assertThat(customerInContext.getName()).isEqualTo("Alice");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Customer saveCustomerInPersistentContext(String name, int age) {
|
||||||
|
Customer customer = new Customer();
|
||||||
|
customer.setName(name);
|
||||||
|
customer.setAge(age);
|
||||||
|
entityManager.persist(customer);
|
||||||
|
return customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void cleanup() {
|
||||||
|
entityManager.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Customer aCustomer() {
|
||||||
|
Customer customer = new Customer();
|
||||||
|
customer.setName("Alice");
|
||||||
|
customer.setAge(30);
|
||||||
|
return customer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityTransaction getTransaction() {
|
||||||
|
EntityTransaction transaction = entityManager.getTransaction();
|
||||||
|
transaction.begin();
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue