From 5bd94409dcf2c2b12b2d14d4e42f62f0ec530702 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 5 Jun 2025 11:06:29 +0200 Subject: [PATCH] Polishing. Revise PersistenceProvider detection to a EntityManagerFactory-based variant, considering EntityManagerFactory proxying. See: #3425 Original pull request: #3885 --- .../data/jpa/provider/JpaClassUtils.java | 2 +- .../jpa/provider/PersistenceProvider.java | 112 +++++++----------- .../PersistenceProviderUnitTests.java | 61 ++++++---- ...ernateCurrentTenantIdentifierResolver.java | 15 +-- .../HibernateMultitenancyTests.java | 28 +++-- .../support/SimpleJpaRepositoryUnitTests.java | 5 +- 6 files changed, 111 insertions(+), 112 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/JpaClassUtils.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/JpaClassUtils.java index f00f4b849..1ae908e37 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/JpaClassUtils.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/JpaClassUtils.java @@ -58,7 +58,7 @@ abstract class JpaClassUtils { return isOfType(metamodel, type, metamodel.getClass().getClassLoader()); } - private static boolean isOfType(Object source, String typeName, @Nullable ClassLoader classLoader) { + static boolean isOfType(Object source, String typeName, @Nullable ClassLoader classLoader) { Assert.notNull(source, "Source instance must not be null"); Assert.hasText(typeName, "Target type name must not be null or empty"); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/PersistenceProvider.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/PersistenceProvider.java index c8628861f..62f0c45f9 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/PersistenceProvider.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/provider/PersistenceProvider.java @@ -25,11 +25,14 @@ import jakarta.persistence.metamodel.IdentifiableType; import jakarta.persistence.metamodel.Metamodel; import jakarta.persistence.metamodel.SingularAttribute; +import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; +import java.util.function.LongSupplier; +import java.util.stream.Stream; import org.eclipse.persistence.config.QueryHints; import org.eclipse.persistence.jpa.JpaQuery; @@ -38,6 +41,8 @@ import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; import org.hibernate.proxy.HibernateProxy; +import org.springframework.aop.framework.AopProxyUtils; +import org.springframework.aop.support.AopUtils; import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; import org.springframework.transaction.support.TransactionSynchronizationManager; @@ -54,22 +59,15 @@ import org.springframework.util.ConcurrentReferenceHashMap; * @author Jens Schauder * @author Greg Turnquist * @author Yuriy Tsarkov - * @author Ariel Morelli Andres (Atlassian US, Inc.) + * @author Ariel Morelli Andres */ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, QueryComment { /** * Hibernate persistence provider. - *

- * Since Hibernate 4.3 the location of the HibernateEntityManager moved to the org.hibernate.jpa package. In order to - * support both locations we interpret both classnames as a Hibernate {@code PersistenceProvider}. - * - * @see DATAJPA-444 */ - HIBERNATE(// - Collections.singletonList(HIBERNATE_ENTITY_MANAGER_FACTORY_INTERFACE), // - Collections.singletonList(HIBERNATE_ENTITY_MANAGER_INTERFACE), // - Collections.singletonList(HIBERNATE_JPA_METAMODEL_TYPE)) { + HIBERNATE(List.of(HIBERNATE_ENTITY_MANAGER_FACTORY_INTERFACE), // + List.of(HIBERNATE_JPA_METAMODEL_TYPE)) { @Override public String extractQueryString(Query query) { @@ -117,9 +115,7 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer /** * EclipseLink persistence provider. */ - ECLIPSELINK(List.of(ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE1, ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE2), - Collections.singleton(ECLIPSELINK_ENTITY_MANAGER_INTERFACE), - Collections.singleton(ECLIPSELINK_JPA_METAMODEL_TYPE)) { + ECLIPSELINK(List.of(ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE), List.of(ECLIPSELINK_JPA_METAMODEL_TYPE)) { @Override public String extractQueryString(Query query) { @@ -157,8 +153,7 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer /** * Unknown special provider. Use standard JPA. */ - GENERIC_JPA(Collections.singleton(GENERIC_JPA_ENTITY_MANAGER_INTERFACE), - Collections.singleton(GENERIC_JPA_ENTITY_MANAGER_INTERFACE), Collections.emptySet()) { + GENERIC_JPA(List.of(GENERIC_JPA_ENTITY_MANAGER_FACTORY_INTERFACE), Collections.emptySet()) { @Nullable @Override @@ -205,8 +200,7 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer private static final Collection ALL = List.of(HIBERNATE, ECLIPSELINK, GENERIC_JPA); private static final ConcurrentReferenceHashMap, PersistenceProvider> CACHE = new ConcurrentReferenceHashMap<>(); - private final Iterable entityManagerFactoryClassNames; - private final Iterable entityManagerClassNames; + final Iterable entityManagerFactoryClassNames; private final Iterable metamodelClassNames; private final boolean present; @@ -216,37 +210,15 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer * * @param entityManagerFactoryClassNames the names of the provider specific * {@link jakarta.persistence.EntityManagerFactory} implementations. Must not be {@literal null} or empty. - * @param entityManagerClassNames the names of the provider specific {@link EntityManager} implementations. Must not - * be {@literal null} or empty. - * @param metamodelClassNames must not be {@literal null}. + * @param metamodelClassNames the names of the provider specific {@link Metamodel} implementations. Must not be + * {@literal null} or empty. */ - PersistenceProvider(Iterable entityManagerFactoryClassNames, Iterable entityManagerClassNames, - Iterable metamodelClassNames) { + PersistenceProvider(Collection entityManagerFactoryClassNames, Collection metamodelClassNames) { this.entityManagerFactoryClassNames = entityManagerFactoryClassNames; - this.entityManagerClassNames = entityManagerClassNames; this.metamodelClassNames = metamodelClassNames; - - boolean present = false; - for (String emfClassName : entityManagerFactoryClassNames) { - - if (ClassUtils.isPresent(emfClassName, PersistenceProvider.class.getClassLoader())) { - present = true; - break; - } - } - - if (!present) { - for (String entityManagerClassName : entityManagerClassNames) { - - if (ClassUtils.isPresent(entityManagerClassName, PersistenceProvider.class.getClassLoader())) { - present = true; - break; - } - } - } - - this.present = present; + this.present = Stream.concat(entityManagerFactoryClassNames.stream(), metamodelClassNames.stream()) + .anyMatch(it -> ClassUtils.isPresent(it, PersistenceProvider.class.getClassLoader())); } /** @@ -262,32 +234,23 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer } /** - * Determines the {@link PersistenceProvider} from the given {@link EntityManager}. If no special one can be + * Determines the {@link PersistenceProvider} from the given {@link EntityManager} by introspecting + * {@link EntityManagerFactory} via {@link EntityManager#getEntityManagerFactory()}. If no special one can be * determined {@link #GENERIC_JPA} will be returned. + *

+ * This method avoids {@link EntityManager} initialization when using + * {@link org.springframework.orm.jpa.SharedEntityManagerCreator} by accessing + * {@link EntityManager#getEntityManagerFactory()}. * * @param em must not be {@literal null}. * @return will never be {@literal null}. + * @see org.springframework.orm.jpa.SharedEntityManagerCreator */ public static PersistenceProvider fromEntityManager(EntityManager em) { Assert.notNull(em, "EntityManager must not be null"); - Class entityManagerType = em.getDelegate().getClass(); - PersistenceProvider cachedProvider = CACHE.get(entityManagerType); - - if (cachedProvider != null) { - return cachedProvider; - } - - for (PersistenceProvider provider : ALL) { - for (String entityManagerClassName : provider.entityManagerClassNames) { - if (isEntityManagerOfType(em, entityManagerClassName)) { - return cacheAndReturn(entityManagerType, provider); - } - } - } - - return cacheAndReturn(entityManagerType, GENERIC_JPA); + return fromEntityManagerFactory(em.getEntityManagerFactory()); } /** @@ -296,12 +259,24 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer * * @param emf must not be {@literal null}. * @return will never be {@literal null}. + * @since 3.5.1 */ public static PersistenceProvider fromEntityManagerFactory(EntityManagerFactory emf) { Assert.notNull(emf, "EntityManagerFactory must not be null"); - Class entityManagerType = emf.getPersistenceUnitUtil().getClass(); + EntityManagerFactory unwrapped = emf; + + while (Proxy.isProxyClass(unwrapped.getClass()) || AopUtils.isAopProxy(unwrapped)) { + + if (Proxy.isProxyClass(unwrapped.getClass())) { + unwrapped = unwrapped.unwrap(null); + } else if (AopUtils.isAopProxy(unwrapped)) { + unwrapped = (EntityManagerFactory) AopProxyUtils.getSingletonTarget(unwrapped); + } + } + + Class entityManagerType = unwrapped.getClass(); PersistenceProvider cachedProvider = CACHE.get(entityManagerType); if (cachedProvider != null) { @@ -310,8 +285,7 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer for (PersistenceProvider provider : ALL) { for (String emfClassName : provider.entityManagerFactoryClassNames) { - if (isOfType(emf.getPersistenceUnitUtil(), emfClassName, - emf.getPersistenceUnitUtil().getClass().getClassLoader())) { + if (isOfType(unwrapped, emfClassName, unwrapped.getClass().getClassLoader())) { return cacheAndReturn(entityManagerType, provider); } } @@ -408,16 +382,14 @@ public enum PersistenceProvider implements QueryExtractor, ProxyIdAccessor, Quer String GENERIC_JPA_ENTITY_MANAGER_FACTORY_INTERFACE = "jakarta.persistence.EntityManagerFactory"; String GENERIC_JPA_ENTITY_MANAGER_INTERFACE = "jakarta.persistence.EntityManager"; - String ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE1 = "org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate"; - String ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE2 = "org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl"; + String ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE = "org.eclipse.persistence.jpa.JpaEntityManagerFactory"; String ECLIPSELINK_ENTITY_MANAGER_INTERFACE = "org.eclipse.persistence.jpa.JpaEntityManager"; + String ECLIPSELINK_JPA_METAMODEL_TYPE = "org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl"; // needed as Spring only exposes that interface via the EM proxy - String HIBERNATE_ENTITY_MANAGER_FACTORY_INTERFACE = "org.hibernate.jpa.internal.PersistenceUnitUtilImpl"; - String HIBERNATE_ENTITY_MANAGER_INTERFACE = "org.hibernate.engine.spi.SessionImplementor"; - + String HIBERNATE_ENTITY_MANAGER_FACTORY_INTERFACE = "org.hibernate.SessionFactory"; + String HIBERNATE_ENTITY_MANAGER_INTERFACE = "org.hibernate.Session"; String HIBERNATE_JPA_METAMODEL_TYPE = "org.hibernate.metamodel.model.domain.JpaMetamodel"; - String ECLIPSELINK_JPA_METAMODEL_TYPE = "org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl"; } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/provider/PersistenceProviderUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/provider/PersistenceProviderUnitTests.java index ba7c3abed..66d55e239 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/provider/PersistenceProviderUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/provider/PersistenceProviderUnitTests.java @@ -16,18 +16,20 @@ package org.springframework.data.jpa.provider; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import static org.springframework.data.jpa.provider.PersistenceProvider.*; import static org.springframework.data.jpa.provider.PersistenceProvider.Constants.*; import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; import java.util.Arrays; import java.util.Map; -import org.assertj.core.api.Assumptions; -import org.hibernate.Version; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mockito; import org.springframework.asm.ClassWriter; @@ -42,6 +44,7 @@ import org.springframework.util.ClassUtils; * @author Thomas Darimont * @author Oliver Gierke * @author Jens Schauder + * @author Mark Paluch */ class PersistenceProviderUnitTests { @@ -56,12 +59,32 @@ class PersistenceProviderUnitTests { this.shadowingClassLoader = new ShadowingClassLoader(getClass().getClassLoader()); } + @ParameterizedTest // GH-3425 + @EnumSource(PersistenceProvider.class) + void entityManagerFactoryClassNamesAreInterfaces(PersistenceProvider provider) throws ClassNotFoundException { + + for (String className : provider.entityManagerFactoryClassNames) { + assertThat(ClassUtils.forName(className, PersistenceProvider.class.getClassLoader()).isInterface()).isTrue(); + } + } + + @ParameterizedTest // GH-3425 + @EnumSource(PersistenceProvider.class) + void metaModelNamesExist(PersistenceProvider provider) throws ClassNotFoundException { + + for (String className : provider.entityManagerFactoryClassNames) { + assertThat(ClassUtils.forName(className, PersistenceProvider.class.getClassLoader()).isInterface()).isNotNull(); + } + } + @Test void detectsEclipseLinkPersistenceProvider() throws Exception { shadowingClassLoader.excludePackage("org.eclipse.persistence.jpa"); EntityManager em = mockProviderSpecificEntityManagerInterface(ECLIPSELINK_ENTITY_MANAGER_INTERFACE); + when(em.getEntityManagerFactory()) + .thenReturn(mockProviderSpecificEntityManagerFactoryInterface(ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE)); assertThat(fromEntityManager(em)).isEqualTo(ECLIPSELINK); } @@ -70,31 +93,19 @@ class PersistenceProviderUnitTests { void fallbackToGenericJpaForUnknownPersistenceProvider() throws Exception { EntityManager em = mockProviderSpecificEntityManagerInterface("foo.bar.unknown.jpa.JpaEntityManager"); + when(em.getEntityManagerFactory()).thenReturn(mock(EntityManagerFactory.class)); assertThat(fromEntityManager(em)).isEqualTo(GENERIC_JPA); } - @Test // DATAJPA-1019 - void detectsHibernatePersistenceProviderForHibernateVersion52() throws Exception { - - Assumptions.assumeThat(Version.getVersionString()).startsWith("5.2"); - - shadowingClassLoader.excludePackage("org.hibernate"); - - EntityManager em = mockProviderSpecificEntityManagerInterface(HIBERNATE_ENTITY_MANAGER_INTERFACE); - - assertThat(fromEntityManager(em)).isEqualTo(HIBERNATE); - } - @Test // DATAJPA-1379 void detectsProviderFromProxiedEntityManager() throws Exception { shadowingClassLoader.excludePackage("org.eclipse.persistence.jpa"); - EntityManager em = mockProviderSpecificEntityManagerInterface(ECLIPSELINK_ENTITY_MANAGER_INTERFACE); - EntityManager emProxy = Mockito.mock(EntityManager.class); - Mockito.when(emProxy.getDelegate()).thenReturn(em); + when(emProxy.getEntityManagerFactory()) + .thenReturn(mockProviderSpecificEntityManagerFactoryInterface(ECLIPSELINK_ENTITY_MANAGER_FACTORY_INTERFACE)); assertThat(fromEntityManager(emProxy)).isEqualTo(ECLIPSELINK); } @@ -105,13 +116,23 @@ class PersistenceProviderUnitTests { EntityManager.class); EntityManager em = (EntityManager) Mockito.mock(providerSpecificEntityManagerInterface); - Mockito.when(em.getDelegate()).thenReturn(em); // delegate is used to determine the classloader of the provider - // specific interface, therefore we return the proxied - // EntityManager. + + // delegate is used to determine the classloader of the provider + // specific interface, therefore we return the proxied EntityManager + when(em.getDelegate()).thenReturn(em); return em; } + private EntityManagerFactory mockProviderSpecificEntityManagerFactoryInterface(String interfaceName) + throws ClassNotFoundException { + + Class providerSpecificEntityManagerInterface = InterfaceGenerator.generate(interfaceName, shadowingClassLoader, + EntityManager.class); + + return (EntityManagerFactory) Mockito.mock(providerSpecificEntityManagerInterface); + } + static class InterfaceGenerator implements Opcodes { static Class generate(final String interfaceName, ClassLoader parentClassLoader, final Class... interfaces) diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateCurrentTenantIdentifierResolver.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateCurrentTenantIdentifierResolver.java index 436e99fb3..d3b87cb00 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateCurrentTenantIdentifierResolver.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateCurrentTenantIdentifierResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 the original author or authors. + * Copyright 2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,21 +18,21 @@ package org.springframework.data.jpa.repository; import java.util.Optional; import org.hibernate.context.spi.CurrentTenantIdentifierResolver; -import org.jspecify.annotations.Nullable; /** - * {@code CurrentTenantIdentifierResolver} instance for testing + * {@code CurrentTenantIdentifierResolver} instance for testing. * - * @author Ariel Morelli Andres (Atlassian US, Inc.) + * @author Ariel Morelli Andres */ public class HibernateCurrentTenantIdentifierResolver implements CurrentTenantIdentifierResolver { - private static final ThreadLocal<@Nullable String> CURRENT_TENANT_IDENTIFIER = new ThreadLocal<>(); - public static void setTenantIdentifier(String tenantIdentifier) { + private static final ThreadLocal CURRENT_TENANT_IDENTIFIER = new ThreadLocal<>(); + + static void setTenantIdentifier(String tenantIdentifier) { CURRENT_TENANT_IDENTIFIER.set(tenantIdentifier); } - public static void removeTenantIdentifier() { + static void removeTenantIdentifier() { CURRENT_TENANT_IDENTIFIER.remove(); } @@ -46,4 +46,5 @@ public class HibernateCurrentTenantIdentifierResolver implements CurrentTenantId public boolean validateExistingCurrentSessions() { return true; } + } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateMultitenancyTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateMultitenancyTests.java index 3de19e90d..28ebcd176 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateMultitenancyTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/HibernateMultitenancyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 the original author or authors. + * Copyright 2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,14 @@ package org.springframework.data.jpa.repository; import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assumptions.*; +import jakarta.persistence.EntityManager; + import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -36,16 +39,14 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; -import jakarta.persistence.EntityManager; - /** * Tests for repositories that use multi-tenancy. This tests verifies that repositories can be created an injected - * despite not having a tenant available at creation time + * despite not having a tenant available at creation time. * - * @author Ariel Morelli Andres (Atlassian US, Inc.) + * @author Ariel Morelli Andres */ @ExtendWith(SpringExtension.class) -@ContextConfiguration() +@ContextConfiguration class HibernateMultitenancyTests { @Autowired RoleRepository roleRepository; @@ -56,19 +57,23 @@ class HibernateMultitenancyTests { HibernateCurrentTenantIdentifierResolver.removeTenantIdentifier(); } - @Test + @Test // GH-3425 void testPersistenceProviderFromFactoryWithoutTenant() { - PersistenceProvider provider = PersistenceProvider.fromEntityManagerFactory(em.getEntityManagerFactory()); + + PersistenceProvider provider = PersistenceProvider.fromEntityManager(em); + assumeThat(provider).isEqualTo(PersistenceProvider.HIBERNATE); } - @Test + @Test // GH-3425 void testRepositoryWithTenant() { + HibernateCurrentTenantIdentifierResolver.setTenantIdentifier("tenant-id"); + assertThatNoException().isThrownBy(() -> roleRepository.findAll()); } - @Test + @Test // GH-3425 void testRepositoryWithoutTenantFails() { assertThatThrownBy(() -> roleRepository.findAll()).isInstanceOf(RuntimeException.class); } @@ -80,9 +85,10 @@ class HibernateMultitenancyTests { return roleRepository.findAll(); } - @ImportResource({ "classpath:multitenancy-test.xml" }) + @ImportResource("classpath:multitenancy-test.xml") @Configuration @EnableJpaRepositories(basePackageClasses = HibernateRepositoryTests.class, considerNestedRepositories = true, includeFilters = @ComponentScan.Filter(classes = { RoleRepository.class }, type = FilterType.ASSIGNABLE_TYPE)) static class TestConfig {} + } diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/SimpleJpaRepositoryUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/SimpleJpaRepositoryUnitTests.java index eac8e8e82..7613dd94c 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/SimpleJpaRepositoryUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/support/SimpleJpaRepositoryUnitTests.java @@ -44,6 +44,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; + import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.sample.User; import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType; @@ -59,7 +60,7 @@ import org.springframework.transaction.annotation.Transactional; * @author Jens Schauder * @author Greg Turnquist * @author Yanming Zhou - * @author Ariel Morelli Andres (Atlassian US, Inc.) + * @author Ariel Morelli Andres */ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) @@ -189,7 +190,6 @@ class SimpleJpaRepositoryUnitTests { newUser.setId(null); when(em.getEntityManagerFactory()).thenReturn(entityManagerFactory); - when(entityManagerFactory.getPersistenceUnitUtil()).thenReturn(persistenceUnitUtil); repo.delete(newUser); @@ -206,7 +206,6 @@ class SimpleJpaRepositoryUnitTests { when(information.isNew(newUser)).thenReturn(false); when(em.getEntityManagerFactory()).thenReturn(entityManagerFactory); - when(entityManagerFactory.getPersistenceUnitUtil()).thenReturn(persistenceUnitUtil); when(persistenceUnitUtil.getIdentifier(any())).thenReturn(23); when(em.find(User.class, 23)).thenReturn(null);