Skip to content

Commit 26f70bf

Browse files
committed
DATAJPA-931 - Avoid unnecessary merging on save.
Checking if entity is already attached to entity manager before calling merge. Fixed one test that was relying on the implicit flush triggered by the save. See also: https://vladmihalcea.com/2016/07/19/jpa-persist-and-merge/
1 parent f780374 commit 26f70bf

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
* @author Mark Paluch
6767
* @author Christoph Strobl
6868
* @author Stefan Fussenegger
69+
* @author Jens Schauder
6970
* @param <T> the type of the entity to handle
7071
* @param <ID> the type of the entity's identifier
7172
*/
@@ -487,9 +488,11 @@ public <S extends T> S save(S entity) {
487488
if (entityInformation.isNew(entity)) {
488489
em.persist(entity);
489490
return entity;
490-
} else {
491+
} else if (!em.contains(entity)) {
491492
return em.merge(entity);
492493
}
494+
495+
return entity;
493496
}
494497

495498
/*

src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerTests.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* Integration test for {@link AuditingEntityListener}.
4242
*
4343
* @author Oliver Gierke
44+
* @author Jens Schauder
4445
*/
4546
@RunWith(SpringJUnit4ClassRunner.class)
4647
@ContextConfiguration("classpath:auditing/auditing-entity-listener.xml")
@@ -89,7 +90,9 @@ public void auditsTransitiveEntitiesCorrectly() {
8990
role.setName("ADMIN");
9091

9192
user.addRole(role);
92-
repository.save(user);
93+
94+
repository.saveAndFlush(user);
95+
9396
role = user.getRoles().iterator().next();
9497

9598
assertDatesSet(user);

src/test/java/org/springframework/data/jpa/repository/support/SimpleJpaRepositoryUnitTests.java

+25
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* @author Oliver Gierke
4545
* @author Thomas Darimont
4646
* @author Mark Paluch
47+
* @author Jens Schauder
4748
*/
4849
@RunWith(MockitoJUnitRunner.Silent.class)
4950
public class SimpleJpaRepositoryUnitTests {
@@ -131,4 +132,28 @@ public void shouldPropagateConfiguredEntityGraphToFindOne() throws Exception {
131132

132133
verify(em).find(User.class, id, singletonMap(EntityGraphType.LOAD.getKey(), (Object) entityGraph));
133134
}
135+
136+
@Test // DATAJPA-931
137+
public void mergeGetsCalledWhenDetached() {
138+
139+
User detachedUser = new User();
140+
141+
when(em.contains(detachedUser)).thenReturn(false);
142+
143+
repo.save(detachedUser);
144+
145+
verify(em).merge(detachedUser);
146+
}
147+
148+
@Test // DATAJPA-931
149+
public void mergeGetsNotCalledWhenAttached() {
150+
151+
User attachedUser = new User();
152+
153+
when(em.contains(attachedUser)).thenReturn(true);
154+
155+
repo.save(attachedUser);
156+
157+
verify(em, never()).merge(attachedUser);
158+
}
134159
}

0 commit comments

Comments
 (0)