Skip to content

Commit f3b9131

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 b8254a5 commit f3b9131

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
@@ -67,6 +67,7 @@
6767
* @author Thomas Darimont
6868
* @author Mark Paluch
6969
* @author Christoph Strobl
70+
* @author Jens Schauder
7071
* @param <T> the type of the entity to handle
7172
* @param <ID> the type of the entity's identifier
7273
*/
@@ -488,9 +489,11 @@ public <S extends T> S save(S entity) {
488489
if (entityInformation.isNew(entity)) {
489490
em.persist(entity);
490491
return entity;
491-
} else {
492+
} else if (!em.contains(entity)) {
492493
return em.merge(entity);
493494
}
495+
496+
return entity;
494497
}
495498

496499
/*

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)