Skip to content

Commit e3bc7de

Browse files
committed
Make RepositoryItemWriter use CrudRepository#saveAll by default
Before this commit, the `RepositoryItemWriter` did not use `CrudRepository#saveAll` by default and one must override `doWrite` and call it manually, which is not convenient. This commit makes the writer use `CrudRepository#saveAll` by default while keeping the possibility to use another method if desired through the `methodName` parameter. Resolves #3720
1 parent 09646d8 commit e3bc7de

File tree

4 files changed

+59
-9
lines changed

4 files changed

+59
-9
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/RepositoryItemWriter.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,6 +36,8 @@
3636
* </p>
3737
*
3838
* <p>
39+
* By default, this writer will use {@link CrudRepository#saveAll(Iterable)}
40+
* to save items, unless another method is selected with {@link #setMethodName(java.lang.String)}.
3941
* It depends on {@link org.springframework.data.repository.CrudRepository#saveAll(Iterable)}
4042
* method to store the items for the chunk. Performance will be determined by that
4143
* implementation more than this writer.
@@ -107,6 +109,11 @@ protected void doWrite(List<? extends T> items) throws Exception {
107109
if (logger.isDebugEnabled()) {
108110
logger.debug("Writing to the repository with " + items.size() + " items.");
109111
}
112+
113+
if (this.methodName == null) {
114+
this.repository.saveAll(items);
115+
return;
116+
}
110117

111118
MethodInvoker invoker = createMethodInvoker(repository, methodName);
112119

@@ -122,6 +129,12 @@ protected void doWrite(List<? extends T> items) throws Exception {
122129
@Override
123130
public void afterPropertiesSet() throws Exception {
124131
Assert.state(repository != null, "A CrudRepository implementation is required");
132+
if (this.methodName != null) {
133+
Assert.hasText(this.methodName, "methodName must not be empty.");
134+
}
135+
else {
136+
logger.debug("No method name provided, CrudRepository.saveAll will be used.");
137+
}
125138
}
126139

127140

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemWriterBuilder.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017-2018 the original author or authors.
2+
* Copyright 2017-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,9 @@
1919

2020
import java.lang.reflect.Method;
2121

22+
import org.apache.commons.logging.Log;
23+
import org.apache.commons.logging.LogFactory;
24+
2225
import org.springframework.batch.item.data.RepositoryItemWriter;
2326
import org.springframework.cglib.proxy.Enhancer;
2427
import org.springframework.cglib.proxy.MethodInterceptor;
@@ -36,6 +39,8 @@
3639
*/
3740
public class RepositoryItemWriterBuilder<T> {
3841

42+
private static final Log logger = LogFactory.getLog(RepositoryItemWriterBuilder.class.getName());
43+
3944
private CrudRepository<T, ?> repository;
4045

4146
private String methodName;
@@ -104,12 +109,16 @@ public RepositoryItemWriter<T> build() {
104109
this.repository = this.repositoryMethodReference.getRepository();
105110
}
106111

107-
Assert.hasText(this.methodName, "methodName is required.");
108112
Assert.notNull(this.repository, "repository is required.");
109113

110114
RepositoryItemWriter<T> writer = new RepositoryItemWriter<>();
111-
writer.setMethodName(this.methodName);
112115
writer.setRepository(this.repository);
116+
if (this.methodName != null) {
117+
Assert.hasText(this.methodName, "methodName must not be empty.");
118+
writer.setMethodName(this.methodName);
119+
} else {
120+
logger.debug("No method name provided, CrudRepository.saveAll will be used.");
121+
}
113122
return writer;
114123
}
115124

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/RepositoryItemWriterTests.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2014 the original author or authors.
2+
* Copyright 2013-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,7 +15,9 @@
1515
*/
1616
package org.springframework.batch.item.data;
1717

18+
import static org.junit.Assert.assertEquals;
1819
import static org.junit.Assert.fail;
20+
import static org.mockito.Mockito.never;
1921
import static org.mockito.Mockito.verify;
2022
import static org.mockito.Mockito.verifyZeroInteractions;
2123

@@ -56,6 +58,17 @@ public void testAfterPropertiesSet() throws Exception {
5658
fail();
5759
} catch (IllegalStateException e) {
5860
}
61+
62+
writer.setRepository(repository);
63+
writer.setMethodName("");
64+
65+
try {
66+
writer.afterPropertiesSet();
67+
fail("Expected IllegalArgumentException");
68+
} catch (IllegalArgumentException e) {
69+
// expected
70+
assertEquals("Wrong message for exception: " + e.getMessage(), "methodName must not be empty.", e.getMessage());
71+
}
5972
}
6073

6174
@Test
@@ -74,5 +87,16 @@ public void testWriteItems() throws Exception {
7487
writer.write(items);
7588

7689
verify(repository).save("foo");
90+
verify(repository, never()).saveAll(items);
91+
}
92+
93+
@Test
94+
public void testWriteItemsWithDefaultMethodName() throws Exception {
95+
List<String> items = Collections.singletonList("foo");
96+
97+
writer.setMethodName(null);
98+
writer.write(items);
99+
100+
verify(repository).saveAll(items);
77101
}
78102
}

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemWriterBuilderTests.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434

3535
/**
3636
* @author Glenn Renfro
37+
* @author Mahmoud Ben Hassine
3738
*/
3839
public class RepositoryItemWriterBuilderTests {
3940
@Mock
@@ -58,15 +59,18 @@ public void testNullRepository() throws Exception {
5859
}
5960

6061
@Test
61-
public void testEmptyMethodName() throws Exception {
62+
public void testEmptyMethodName() {
6263
try {
63-
new RepositoryItemWriterBuilder<String>().repository(this.repository).build();
64+
new RepositoryItemWriterBuilder<String>()
65+
.repository(this.repository)
66+
.methodName("")
67+
.build();
6468

6569
fail("IllegalArgumentException should have been thrown");
6670
}
6771
catch (IllegalArgumentException iae) {
6872
assertEquals("IllegalArgumentException message did not match the expected result.",
69-
"methodName is required.", iae.getMessage());
73+
"methodName must not be empty.", iae.getMessage());
7074
}
7175
}
7276

0 commit comments

Comments
 (0)