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/
This commit is contained in:
Jens Schauder
2017-12-08 14:15:02 +01:00
parent f78037410d
commit 26f70bf1f0
3 changed files with 33 additions and 2 deletions

View File

@@ -66,6 +66,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @author Christoph Strobl
* @author Stefan Fussenegger
* @author Jens Schauder
* @param <T> the type of the entity to handle
* @param <ID> the type of the entity's identifier
*/
@@ -487,9 +488,11 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
} else if (!em.contains(entity)) {
return em.merge(entity);
}
return entity;
}
/*

View File

@@ -41,6 +41,7 @@ import org.springframework.transaction.annotation.Transactional;
* Integration test for {@link AuditingEntityListener}.
*
* @author Oliver Gierke
* @author Jens Schauder
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:auditing/auditing-entity-listener.xml")
@@ -89,7 +90,9 @@ public class AuditingEntityListenerTests {
role.setName("ADMIN");
user.addRole(role);
repository.save(user);
repository.saveAndFlush(user);
role = user.getRoles().iterator().next();
assertDatesSet(user);

View File

@@ -44,6 +44,7 @@ import org.springframework.data.repository.CrudRepository;
* @author Oliver Gierke
* @author Thomas Darimont
* @author Mark Paluch
* @author Jens Schauder
*/
@RunWith(MockitoJUnitRunner.Silent.class)
public class SimpleJpaRepositoryUnitTests {
@@ -131,4 +132,28 @@ public class SimpleJpaRepositoryUnitTests {
verify(em).find(User.class, id, singletonMap(EntityGraphType.LOAD.getKey(), (Object) entityGraph));
}
@Test // DATAJPA-931
public void mergeGetsCalledWhenDetached() {
User detachedUser = new User();
when(em.contains(detachedUser)).thenReturn(false);
repo.save(detachedUser);
verify(em).merge(detachedUser);
}
@Test // DATAJPA-931
public void mergeGetsNotCalledWhenAttached() {
User attachedUser = new User();
when(em.contains(attachedUser)).thenReturn(true);
repo.save(attachedUser);
verify(em, never()).merge(attachedUser);
}
}