Unwrap raw target Query instance in case of proxy mismatch
Closes gh-32766
(cherry picked from commit 59a125d06f)
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -390,7 +390,9 @@ public abstract class SharedEntityManagerCreator {
|
|||||||
else if (targetClass.isInstance(proxy)) {
|
else if (targetClass.isInstance(proxy)) {
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
break;
|
else {
|
||||||
|
return this.target.unwrap(targetClass);
|
||||||
|
}
|
||||||
case "getOutputParameterValue":
|
case "getOutputParameterValue":
|
||||||
if (this.entityManager == null) {
|
if (this.entityManager == null) {
|
||||||
Object key = args[0];
|
Object key = args[0];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -38,16 +38,16 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|||||||
import static org.mockito.Mockito.withSettings;
|
import static org.mockito.Mockito.withSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link SharedEntityManagerCreator}.
|
* Tests for {@link SharedEntityManagerCreator}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class SharedEntityManagerCreatorTests {
|
class SharedEntityManagerCreatorTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void proxyingWorksIfInfoReturnsNullEntityManagerInterface() {
|
void proxyingWorksIfInfoReturnsNullEntityManagerInterface() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class,
|
EntityManagerFactory emf = mock(EntityManagerFactory.class,
|
||||||
withSettings().extraInterfaces(EntityManagerFactoryInfo.class));
|
withSettings().extraInterfaces(EntityManagerFactoryInfo.class));
|
||||||
// EntityManagerFactoryInfo.getEntityManagerInterface returns null
|
// EntityManagerFactoryInfo.getEntityManagerInterface returns null
|
||||||
@@ -55,7 +55,7 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionRequiredExceptionOnJoinTransaction() {
|
void transactionRequiredExceptionOnJoinTransaction() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(
|
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(
|
||||||
@@ -63,7 +63,7 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionRequiredExceptionOnFlush() {
|
void transactionRequiredExceptionOnFlush() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(
|
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(
|
||||||
@@ -71,7 +71,7 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionRequiredExceptionOnPersist() {
|
void transactionRequiredExceptionOnPersist() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
||||||
@@ -79,7 +79,7 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionRequiredExceptionOnMerge() {
|
void transactionRequiredExceptionOnMerge() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
||||||
@@ -87,7 +87,7 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionRequiredExceptionOnRemove() {
|
void transactionRequiredExceptionOnRemove() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
||||||
@@ -95,7 +95,7 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactionRequiredExceptionOnRefresh() {
|
void transactionRequiredExceptionOnRefresh() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
assertThatExceptionOfType(TransactionRequiredException.class).isThrownBy(() ->
|
||||||
@@ -103,78 +103,98 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deferredQueryWithUpdate() {
|
void deferredQueryWithUpdate() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager targetEm = mock(EntityManager.class);
|
EntityManager targetEm = mock(EntityManager.class);
|
||||||
Query query = mock(Query.class);
|
Query targetQuery = mock(Query.class);
|
||||||
given(emf.createEntityManager()).willReturn(targetEm);
|
given(emf.createEntityManager()).willReturn(targetEm);
|
||||||
given(targetEm.createQuery("x")).willReturn(query);
|
given(targetEm.createQuery("x")).willReturn(targetQuery);
|
||||||
given(targetEm.isOpen()).willReturn(true);
|
given(targetEm.isOpen()).willReturn(true);
|
||||||
|
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
|
||||||
|
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
em.createQuery("x").executeUpdate();
|
Query query = em.createQuery("x");
|
||||||
|
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
|
||||||
|
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
|
||||||
|
assertThat(query.unwrap(Query.class)).isSameAs(query);
|
||||||
|
query.executeUpdate();
|
||||||
|
|
||||||
verify(query).executeUpdate();
|
verify(targetQuery).executeUpdate();
|
||||||
verify(targetEm).close();
|
verify(targetEm).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deferredQueryWithSingleResult() {
|
void deferredQueryWithSingleResult() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager targetEm = mock(EntityManager.class);
|
EntityManager targetEm = mock(EntityManager.class);
|
||||||
Query query = mock(Query.class);
|
Query targetQuery = mock(Query.class);
|
||||||
given(emf.createEntityManager()).willReturn(targetEm);
|
given(emf.createEntityManager()).willReturn(targetEm);
|
||||||
given(targetEm.createQuery("x")).willReturn(query);
|
given(targetEm.createQuery("x")).willReturn(targetQuery);
|
||||||
given(targetEm.isOpen()).willReturn(true);
|
given(targetEm.isOpen()).willReturn(true);
|
||||||
|
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
|
||||||
|
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
em.createQuery("x").getSingleResult();
|
Query query = em.createQuery("x");
|
||||||
|
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
|
||||||
|
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
|
||||||
|
assertThat(query.unwrap(Query.class)).isSameAs(query);
|
||||||
|
query.getSingleResult();
|
||||||
|
|
||||||
verify(query).getSingleResult();
|
verify(targetQuery).getSingleResult();
|
||||||
verify(targetEm).close();
|
verify(targetEm).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deferredQueryWithResultList() {
|
void deferredQueryWithResultList() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager targetEm = mock(EntityManager.class);
|
EntityManager targetEm = mock(EntityManager.class);
|
||||||
Query query = mock(Query.class);
|
Query targetQuery = mock(Query.class);
|
||||||
given(emf.createEntityManager()).willReturn(targetEm);
|
given(emf.createEntityManager()).willReturn(targetEm);
|
||||||
given(targetEm.createQuery("x")).willReturn(query);
|
given(targetEm.createQuery("x")).willReturn(targetQuery);
|
||||||
given(targetEm.isOpen()).willReturn(true);
|
given(targetEm.isOpen()).willReturn(true);
|
||||||
|
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
|
||||||
|
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
em.createQuery("x").getResultList();
|
Query query = em.createQuery("x");
|
||||||
|
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
|
||||||
|
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
|
||||||
|
assertThat(query.unwrap(Query.class)).isSameAs(query);
|
||||||
|
query.getResultList();
|
||||||
|
|
||||||
verify(query).getResultList();
|
verify(targetQuery).getResultList();
|
||||||
verify(targetEm).close();
|
verify(targetEm).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deferredQueryWithResultStream() {
|
void deferredQueryWithResultStream() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager targetEm = mock(EntityManager.class);
|
EntityManager targetEm = mock(EntityManager.class);
|
||||||
Query query = mock(Query.class);
|
Query targetQuery = mock(Query.class);
|
||||||
given(emf.createEntityManager()).willReturn(targetEm);
|
given(emf.createEntityManager()).willReturn(targetEm);
|
||||||
given(targetEm.createQuery("x")).willReturn(query);
|
given(targetEm.createQuery("x")).willReturn(targetQuery);
|
||||||
given(targetEm.isOpen()).willReturn(true);
|
given(targetEm.isOpen()).willReturn(true);
|
||||||
|
given((Query) targetQuery.unwrap(targetQuery.getClass())).willReturn(targetQuery);
|
||||||
|
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
em.createQuery("x").getResultStream();
|
Query query = em.createQuery("x");
|
||||||
|
assertThat((Query) query.unwrap(null)).isSameAs(targetQuery);
|
||||||
|
assertThat((Query) query.unwrap(targetQuery.getClass())).isSameAs(targetQuery);
|
||||||
|
assertThat(query.unwrap(Query.class)).isSameAs(query);
|
||||||
|
query.getResultStream();
|
||||||
|
|
||||||
verify(query).getResultStream();
|
verify(targetQuery).getResultStream();
|
||||||
verify(targetEm).close();
|
verify(targetEm).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deferredStoredProcedureQueryWithIndexedParameters() {
|
void deferredStoredProcedureQueryWithIndexedParameters() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager targetEm = mock(EntityManager.class);
|
EntityManager targetEm = mock(EntityManager.class);
|
||||||
StoredProcedureQuery query = mock(StoredProcedureQuery.class);
|
StoredProcedureQuery targetQuery = mock(StoredProcedureQuery.class);
|
||||||
given(emf.createEntityManager()).willReturn(targetEm);
|
given(emf.createEntityManager()).willReturn(targetEm);
|
||||||
given(targetEm.createStoredProcedureQuery("x")).willReturn(query);
|
given(targetEm.createStoredProcedureQuery("x")).willReturn(targetQuery);
|
||||||
willReturn("y").given(query).getOutputParameterValue(0);
|
willReturn("y").given(targetQuery).getOutputParameterValue(0);
|
||||||
willReturn("z").given(query).getOutputParameterValue(2);
|
willReturn("z").given(targetQuery).getOutputParameterValue(2);
|
||||||
given(targetEm.isOpen()).willReturn(true);
|
given(targetEm.isOpen()).willReturn(true);
|
||||||
|
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
@@ -188,24 +208,24 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
spq.getOutputParameterValue(1));
|
spq.getOutputParameterValue(1));
|
||||||
assertThat(spq.getOutputParameterValue(2)).isEqualTo("z");
|
assertThat(spq.getOutputParameterValue(2)).isEqualTo("z");
|
||||||
|
|
||||||
verify(query).registerStoredProcedureParameter(0, String.class, ParameterMode.OUT);
|
verify(targetQuery).registerStoredProcedureParameter(0, String.class, ParameterMode.OUT);
|
||||||
verify(query).registerStoredProcedureParameter(1, Number.class, ParameterMode.IN);
|
verify(targetQuery).registerStoredProcedureParameter(1, Number.class, ParameterMode.IN);
|
||||||
verify(query).registerStoredProcedureParameter(2, Object.class, ParameterMode.INOUT);
|
verify(targetQuery).registerStoredProcedureParameter(2, Object.class, ParameterMode.INOUT);
|
||||||
verify(query).execute();
|
verify(targetQuery).execute();
|
||||||
verify(targetEm).close();
|
verify(targetEm).close();
|
||||||
verifyNoMoreInteractions(query);
|
verifyNoMoreInteractions(targetQuery);
|
||||||
verifyNoMoreInteractions(targetEm);
|
verifyNoMoreInteractions(targetEm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deferredStoredProcedureQueryWithNamedParameters() {
|
void deferredStoredProcedureQueryWithNamedParameters() {
|
||||||
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
EntityManagerFactory emf = mock(EntityManagerFactory.class);
|
||||||
EntityManager targetEm = mock(EntityManager.class);
|
EntityManager targetEm = mock(EntityManager.class);
|
||||||
StoredProcedureQuery query = mock(StoredProcedureQuery.class);
|
StoredProcedureQuery targetQuery = mock(StoredProcedureQuery.class);
|
||||||
given(emf.createEntityManager()).willReturn(targetEm);
|
given(emf.createEntityManager()).willReturn(targetEm);
|
||||||
given(targetEm.createStoredProcedureQuery("x")).willReturn(query);
|
given(targetEm.createStoredProcedureQuery("x")).willReturn(targetQuery);
|
||||||
willReturn("y").given(query).getOutputParameterValue("a");
|
willReturn("y").given(targetQuery).getOutputParameterValue("a");
|
||||||
willReturn("z").given(query).getOutputParameterValue("c");
|
willReturn("z").given(targetQuery).getOutputParameterValue("c");
|
||||||
given(targetEm.isOpen()).willReturn(true);
|
given(targetEm.isOpen()).willReturn(true);
|
||||||
|
|
||||||
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
EntityManager em = SharedEntityManagerCreator.createSharedEntityManager(emf);
|
||||||
@@ -219,12 +239,12 @@ public class SharedEntityManagerCreatorTests {
|
|||||||
spq.getOutputParameterValue("b"));
|
spq.getOutputParameterValue("b"));
|
||||||
assertThat(spq.getOutputParameterValue("c")).isEqualTo("z");
|
assertThat(spq.getOutputParameterValue("c")).isEqualTo("z");
|
||||||
|
|
||||||
verify(query).registerStoredProcedureParameter("a", String.class, ParameterMode.OUT);
|
verify(targetQuery).registerStoredProcedureParameter("a", String.class, ParameterMode.OUT);
|
||||||
verify(query).registerStoredProcedureParameter("b", Number.class, ParameterMode.IN);
|
verify(targetQuery).registerStoredProcedureParameter("b", Number.class, ParameterMode.IN);
|
||||||
verify(query).registerStoredProcedureParameter("c", Object.class, ParameterMode.INOUT);
|
verify(targetQuery).registerStoredProcedureParameter("c", Object.class, ParameterMode.INOUT);
|
||||||
verify(query).execute();
|
verify(targetQuery).execute();
|
||||||
verify(targetEm).close();
|
verify(targetEm).close();
|
||||||
verifyNoMoreInteractions(query);
|
verifyNoMoreInteractions(targetQuery);
|
||||||
verifyNoMoreInteractions(targetEm);
|
verifyNoMoreInteractions(targetEm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user