PersistenceAnnotationBeanPostProcessor defensively handles BeanDefinition access for extended EntityManagers

Issue: SPR-8834
(cherry picked from commit 592e344)
This commit is contained in:
Juergen Hoeller
2014-08-22 00:01:39 +02:00
parent e89f18bf6d
commit 388561df61
2 changed files with 33 additions and 13 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -691,8 +691,8 @@ public class PersistenceAnnotationBeanPostProcessor
// Inject a container-managed extended EntityManager.
em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(emf, this.properties);
}
if (em instanceof EntityManagerProxy &&
beanFactory != null && !beanFactory.isPrototype(requestingBeanName)) {
if (em instanceof EntityManagerProxy && beanFactory != null &&
beanFactory.containsBean(requestingBeanName) && !beanFactory.isPrototype(requestingBeanName)) {
extendedEntityManagersToClose.put(target, ((EntityManagerProxy) em).getTargetEntityManager());
}
return em;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2014 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.
@@ -23,7 +23,6 @@ import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
@@ -34,6 +33,7 @@ import javax.persistence.PersistenceUnit;
import org.hibernate.ejb.HibernateEntityManager;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -140,6 +140,26 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
verify(mockEm2).flush();
}
@Test
public void testInjectionIntoExistingObjects() {
EntityManager mockEm = mock(EntityManager.class);
given(mockEmf.createEntityManager()).willReturn(mockEm);
GenericApplicationContext gac = new GenericApplicationContext();
gac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", mockEmf);
gac.registerBeanDefinition("annotationProcessor",
new RootBeanDefinition(PersistenceAnnotationBeanPostProcessor.class));
gac.refresh();
DefaultPrivatePersistenceContextField existingBean1 = new DefaultPrivatePersistenceContextField();
gac.getAutowireCapableBeanFactory().autowireBean(existingBean1);
assertNotNull(existingBean1.em);
DefaultPublicPersistenceContextSetter existingBean2 = new DefaultPublicPersistenceContextSetter();
gac.getAutowireCapableBeanFactory().autowireBean(existingBean2);
assertNotNull(existingBean2.em);
}
@Test
public void testPublicExtendedPersistenceContextSetterWithSerialization() throws Exception {
DummyInvocationHandler ih = new DummyInvocationHandler();
@@ -524,7 +544,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
public void testFieldOfWrongTypeAnnotatedWithPersistenceUnit() {
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
try {
babpp.postProcessPropertyValues(null, null, new FieldOfWrongTypeAnnotatedWithPersistenceUnit(), null);
babpp.postProcessPropertyValues(null, null, new FieldOfWrongTypeAnnotatedWithPersistenceUnit(), "bean");
fail("Can't inject this field");
}
catch (IllegalStateException ex) {
@@ -536,7 +556,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
public void testSetterOfWrongTypeAnnotatedWithPersistenceUnit() {
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
try {
babpp.postProcessPropertyValues(null, null, new SetterOfWrongTypeAnnotatedWithPersistenceUnit(), null);
babpp.postProcessPropertyValues(null, null, new SetterOfWrongTypeAnnotatedWithPersistenceUnit(), "bean");
fail("Can't inject this setter");
}
catch (IllegalStateException ex) {
@@ -548,7 +568,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
public void testSetterWithNoArgs() {
PersistenceAnnotationBeanPostProcessor babpp = new PersistenceAnnotationBeanPostProcessor();
try {
babpp.postProcessPropertyValues(null, null, new SetterWithNoArgs(), null);
babpp.postProcessPropertyValues(null, null, new SetterWithNoArgs(), "bean");
fail("Can't inject this setter");
}
catch (IllegalStateException ex) {
@@ -593,7 +613,7 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
PersistenceAnnotationBeanPostProcessor babpp = new MockPersistenceAnnotationBeanPostProcessor();
DefaultPrivatePersistenceContextFieldWithProperties transactionalField =
new DefaultPrivatePersistenceContextFieldWithProperties();
babpp.postProcessPropertyValues(null, null, transactionalField, null);
babpp.postProcessPropertyValues(null, null, transactionalField, "bean");
assertNotNull(transactionalField.em);
assertNotNull(transactionalField.em.getDelegate());
@@ -620,8 +640,8 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, null);
babpp.postProcessPropertyValues(null, null, transactionalField, null);
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, "bean1");
babpp.postProcessPropertyValues(null, null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);
@@ -653,8 +673,8 @@ public class PersistenceInjectionTests extends AbstractEntityManagerFactoryBeanT
new DefaultPrivatePersistenceContextFieldWithProperties();
DefaultPrivatePersistenceContextField transactionalField = new DefaultPrivatePersistenceContextField();
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, null);
babpp.postProcessPropertyValues(null, null, transactionalField, null);
babpp.postProcessPropertyValues(null, null, transactionalFieldWithProperties, "bean1");
babpp.postProcessPropertyValues(null, null, transactionalField, "bean2");
assertNotNull(transactionalFieldWithProperties.em);
assertNotNull(transactionalField.em);