diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 31abc19187..67e437917c 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -195,7 +195,13 @@ public void delete(T entity) { return; } - entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity)); + if (entityInformation.getVersionAttribute().isPresent()) { + // call merge() to raise ObjectOptimisticLockingFailureException if entity is stale + entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity)); + } + else { + entityManager.remove(existing); + } } @Override diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java index 379dec5177..addb9d866d 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java @@ -16,6 +16,9 @@ package org.springframework.data.jpa.repository.support; import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import jakarta.persistence.EntityManager; import jakarta.persistence.OptimisticLockException; @@ -29,6 +32,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; import org.springframework.data.jpa.domain.sample.PersistableWithIdClass; import org.springframework.data.jpa.domain.sample.PersistableWithIdClassPK; import org.springframework.data.jpa.domain.sample.SampleEntity; @@ -57,13 +61,16 @@ class JpaRepositoryTests { @PersistenceContext EntityManager em; + private EntityManager spiedEntityManager; + private JpaRepository repository; private CrudRepository idClassRepository; private JpaRepository versionedUserRepository; @BeforeEach void setUp() { - repository = new JpaRepositoryFactory(em).getRepository(SampleEntityRepository.class); + spiedEntityManager = Mockito.spy(em); + repository = new JpaRepositoryFactory(spiedEntityManager).getRepository(SampleEntityRepository.class); idClassRepository = new JpaRepositoryFactory(em).getRepository(SampleWithIdClassRepository.class); versionedUserRepository = new JpaRepositoryFactory(em).getRepository(VersionedUserRepository.class); } @@ -187,6 +194,18 @@ void deleteStaleVersionedEntityShouldRaiseOptimisticLockException() { }); } + @Test //GH-3401 + void deleteNonVersionedEntityShouldNotInvokeMerge() { + SampleEntity entity = new SampleEntity("one", "eins"); + repository.save(entity); + repository.flush(); + em.detach(entity); + + reset(spiedEntityManager); + repository.delete(entity); + then(spiedEntityManager).should(never()).merge(entity); + } + private interface SampleEntityRepository extends JpaRepository { }