diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaItemWriter.java index a3e531c3a..6c2b4911c 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JpaItemWriter.java @@ -43,6 +43,7 @@ import org.springframework.util.Assert; * * @author Thomas Risberg * @author Mahmoud Ben Hassine + * @author Jinwoo Bae * */ public class JpaItemWriter implements ItemWriter, InitializingBean { @@ -53,6 +54,8 @@ public class JpaItemWriter implements ItemWriter, InitializingBean { private boolean usePersist = false; + private boolean clearEntityManager = true; + /** * Set the EntityManager to be used internally. * @param entityManagerFactory the entityManagerFactory to set @@ -69,6 +72,15 @@ public class JpaItemWriter implements ItemWriter, InitializingBean { this.usePersist = usePersist; } + /** + * Flag to indicate that the EntityManager should be cleared and flushed at the end of + * the write (default true). + * @param clearEntityManager the flag value to set + */ + public void setClearEntityManager(boolean clearEntityManager) { + this.clearEntityManager = clearEntityManager; + } + /** * Check mandatory properties - there must be an entityManagerFactory. */ @@ -91,6 +103,9 @@ public class JpaItemWriter implements ItemWriter, InitializingBean { } doWrite(entityManager, items); entityManager.flush(); + if (clearEntityManager) { + entityManager.clear(); + } } /** diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilder.java index 7fd536d1a..f6a96c2fa 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.springframework.util.Assert; * A builder for the {@link JpaItemWriter}. * * @author Mahmoud Ben Hassine + * @author Jinwoo Bae * @since 4.1 * @see JpaItemWriter */ @@ -33,6 +34,8 @@ public class JpaItemWriterBuilder { private boolean usePersist = false; + private boolean clearEntityManager = true; + /** * The JPA {@link EntityManagerFactory} to obtain an entity manager from. Required. * @param entityManagerFactory the {@link EntityManagerFactory} @@ -57,6 +60,19 @@ public class JpaItemWriterBuilder { return this; } + /** + * If set to false, the {@link jakarta.persistence.EntityManager} will not be cleared + * at the end of the chunk. + * @param clearEntityManager defaults to true + * @return this instance for method chaining + * @see org.springframework.batch.item.database.JpaItemWriter#setClearEntityManager(boolean) + */ + public JpaItemWriterBuilder clearEntityManager(boolean clearEntityManager) { + this.clearEntityManager = clearEntityManager; + + return this; + } + /** * Returns a fully built {@link JpaItemWriter}. * @return the writer @@ -67,6 +83,7 @@ public class JpaItemWriterBuilder { JpaItemWriter writer = new JpaItemWriter<>(); writer.setEntityManagerFactory(this.entityManagerFactory); writer.setUsePersist(this.usePersist); + writer.setClearEntityManager(this.clearEntityManager); return writer; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilderTests.java index cde0a34ff..9a2509e2d 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/builder/JpaItemWriterBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 the original author or authors. + * Copyright 2018-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,10 +32,12 @@ import org.springframework.transaction.support.TransactionSynchronizationManager import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; /** * @author Mahmoud Ben Hassine + * @author Jinwoo Bae */ @ExtendWith(MockitoExtension.class) class JpaItemWriterBuilderTests { @@ -71,6 +73,23 @@ class JpaItemWriterBuilderTests { verify(this.entityManager).merge(chunk.getItems().get(0)); verify(this.entityManager).merge(chunk.getItems().get(1)); + verify(this.entityManager).clear(); + } + + @Test + void testConfigurationClearEntityManager() throws Exception { + JpaItemWriter itemWriter = new JpaItemWriterBuilder().clearEntityManager(false) + .entityManagerFactory(this.entityManagerFactory).build(); + + itemWriter.afterPropertiesSet(); + + Chunk chunk = Chunk.of("foo", "bar"); + + itemWriter.write(chunk); + + verify(this.entityManager).merge(chunk.getItems().get(0)); + verify(this.entityManager).merge(chunk.getItems().get(1)); + verify(this.entityManager, never()).clear(); } @Test