Browse Source

Merge branch '5.1.x'

pull/22705/head
Juergen Hoeller 6 years ago
parent
commit
673be7fb0d
  1. 37
      spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java
  2. 81
      spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests.java
  3. 5
      spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/beans/NoDefinitionInSpringContextTestBean.java
  4. 2
      spring-orm/src/test/resources/org/springframework/orm/jpa/hibernate/hibernate-manager-native.xml

37
spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringBeanContainer.java

@ -26,6 +26,7 @@ import org.hibernate.resource.beans.container.spi.ContainedBean; @@ -26,6 +26,7 @@ import org.hibernate.resource.beans.container.spi.ContainedBean;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.lang.Nullable;
@ -155,7 +156,22 @@ public final class SpringBeanContainer implements BeanContainer { @@ -155,7 +156,22 @@ public final class SpringBeanContainer implements BeanContainer {
logger.debug("Falling back to Hibernate's default producer after bean creation failure for " +
beanType + ": " + ex);
}
return new SpringContainedBean<>(fallbackProducer.produceBeanInstance(beanType));
try {
return new SpringContainedBean<>(fallbackProducer.produceBeanInstance(beanType));
}
catch (RuntimeException ex2) {
if (ex instanceof BeanCreationException) {
if (logger.isDebugEnabled()) {
logger.debug("Fallback producer failed for " + beanType + ": " + ex2);
}
// Rethrow original Spring exception from first attempt.
throw ex;
}
else {
// Throw fallback producer exception since original was probably NoSuchBeanDefinitionException.
throw ex2;
}
}
}
}
@ -177,9 +193,24 @@ public final class SpringBeanContainer implements BeanContainer { @@ -177,9 +193,24 @@ public final class SpringBeanContainer implements BeanContainer {
catch (BeansException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Falling back to Hibernate's default producer after bean creation failure for " +
beanType + ": " + ex);
beanType + " with name '" + name + "': " + ex);
}
try {
return new SpringContainedBean<>(fallbackProducer.produceBeanInstance(name, beanType));
}
catch (RuntimeException ex2) {
if (ex instanceof BeanCreationException) {
if (logger.isDebugEnabled()) {
logger.debug("Fallback producer failed for " + beanType + " with name '" + name + "': " + ex2);
}
// Rethrow original Spring exception from first attempt.
throw ex;
}
else {
// Throw fallback producer exception since original was probably NoSuchBeanDefinitionException.
throw ex2;
}
}
return new SpringContainedBean<>(fallbackProducer.produceBeanInstance(name, beanType));
}
}

81
spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests.java

@ -16,19 +16,24 @@ @@ -16,19 +16,24 @@
package org.springframework.orm.jpa.hibernate;
import javax.persistence.AttributeConverter;
import org.hibernate.SessionFactory;
import org.hibernate.resource.beans.container.spi.BeanContainer;
import org.hibernate.resource.beans.container.spi.ContainedBean;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.AbstractEntityManagerFactoryIntegrationTests;
import org.springframework.orm.jpa.hibernate.beans.*;
import org.springframework.orm.jpa.hibernate.beans.BeanSource;
import org.springframework.orm.jpa.hibernate.beans.MultiplePrototypesInSpringContextTestBean;
import org.springframework.orm.jpa.hibernate.beans.NoDefinitionInSpringContextTestBean;
import org.springframework.orm.jpa.hibernate.beans.SinglePrototypeInSpringContextTestBean;
import static org.junit.Assert.*;
@ -36,6 +41,7 @@ import static org.junit.Assert.*; @@ -36,6 +41,7 @@ import static org.junit.Assert.*;
* Hibernate-specific SpringBeanContainer integration tests.
*
* @author Yoann Rodiere
* @author Juergen Hoeller
*/
public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTests
extends AbstractEntityManagerFactoryIntegrationTests {
@ -51,9 +57,9 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -51,9 +57,9 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
}
private ManagedBeanRegistry getManagedBeanRegistry() {
SessionFactory sessionFactory = entityManagerFactory.unwrap( SessionFactory.class );
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
ServiceRegistry serviceRegistry = sessionFactory.getSessionFactoryOptions().getServiceRegistry();
return serviceRegistry.requireService( ManagedBeanRegistry.class );
return serviceRegistry.requireService(ManagedBeanRegistry.class);
}
private BeanContainer getBeanContainer() {
@ -68,8 +74,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -68,8 +74,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<SinglePrototypeInSpringContextTestBean> bean = beanContainer.getBean(
SinglePrototypeInSpringContextTestBean.class,
JpaLifecycleOptions.INSTANCE,
IneffectiveBeanInstanceProducer.INSTANCE
JpaLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
assertNotNull(bean);
@ -85,8 +90,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -85,8 +90,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<MultiplePrototypesInSpringContextTestBean> bean = beanContainer.getBean(
"multiple-1", MultiplePrototypesInSpringContextTestBean.class,
JpaLifecycleOptions.INSTANCE,
IneffectiveBeanInstanceProducer.INSTANCE
JpaLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
assertNotNull(bean);
@ -103,8 +107,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -103,8 +107,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<SinglePrototypeInSpringContextTestBean> bean = beanContainer.getBean(
SinglePrototypeInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE,
IneffectiveBeanInstanceProducer.INSTANCE
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
assertNotNull(bean);
@ -115,8 +118,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -115,8 +118,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<SinglePrototypeInSpringContextTestBean> bean2 = beanContainer.getBean(
SinglePrototypeInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE,
IneffectiveBeanInstanceProducer.INSTANCE
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
assertNotNull(bean2);
@ -133,8 +135,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -133,8 +135,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<MultiplePrototypesInSpringContextTestBean> bean = beanContainer.getBean(
"multiple-1", MultiplePrototypesInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE,
IneffectiveBeanInstanceProducer.INSTANCE
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
assertNotNull(bean);
@ -145,8 +146,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -145,8 +146,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<MultiplePrototypesInSpringContextTestBean> bean2 = beanContainer.getBean(
"multiple-1", MultiplePrototypesInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE,
IneffectiveBeanInstanceProducer.INSTANCE
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
assertNotNull(bean2);
@ -164,8 +164,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -164,8 +164,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<NoDefinitionInSpringContextTestBean> bean = beanContainer.getBean(
NoDefinitionInSpringContextTestBean.class,
JpaLifecycleOptions.INSTANCE,
fallbackProducer
JpaLifecycleOptions.INSTANCE, fallbackProducer
);
assertEquals(1, fallbackProducer.currentUnnamedInstantiationCount());
@ -186,8 +185,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -186,8 +185,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<NoDefinitionInSpringContextTestBean> bean = beanContainer.getBean(
"some name", NoDefinitionInSpringContextTestBean.class,
JpaLifecycleOptions.INSTANCE,
fallbackProducer
JpaLifecycleOptions.INSTANCE, fallbackProducer
);
assertEquals(0, fallbackProducer.currentUnnamedInstantiationCount());
@ -209,8 +207,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -209,8 +207,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<NoDefinitionInSpringContextTestBean> bean = beanContainer.getBean(
NoDefinitionInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE,
fallbackProducer
NativeLifecycleOptions.INSTANCE, fallbackProducer
);
assertEquals(1, fallbackProducer.currentUnnamedInstantiationCount());
@ -231,8 +228,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -231,8 +228,7 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
ContainedBean<NoDefinitionInSpringContextTestBean> bean = beanContainer.getBean(
"some name", NoDefinitionInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE,
fallbackProducer
NativeLifecycleOptions.INSTANCE, fallbackProducer
);
assertEquals(0, fallbackProducer.currentUnnamedInstantiationCount());
@ -246,11 +242,40 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -246,11 +242,40 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
assertNull(instance.getApplicationContext());
}
@Test(expected = UnsupportedOperationException.class)
public void testFallbackExceptionInCaseOfNoSpringBeanFound() {
getBeanContainer().getBean(NoDefinitionInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
}
@Test(expected = BeanCreationException.class)
public void testOriginalExceptionInCaseOfFallbackProducerFailure() {
getBeanContainer().getBean(AttributeConverter.class,
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
}
@Test(expected = UnsupportedOperationException.class)
public void testFallbackExceptionInCaseOfNoSpringBeanFoundByName() {
getBeanContainer().getBean("some name", NoDefinitionInSpringContextTestBean.class,
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
}
@Test(expected = BeanCreationException.class)
public void testOriginalExceptionInCaseOfFallbackProducerFailureByName() {
getBeanContainer().getBean("invalid", AttributeConverter.class,
NativeLifecycleOptions.INSTANCE, IneffectiveBeanInstanceProducer.INSTANCE
);
}
/**
* The lifecycle options mandated by the JPA spec and used as a default in Hibernate ORM.
*/
private static class JpaLifecycleOptions implements BeanContainer.LifecycleOptions {
public static final JpaLifecycleOptions INSTANCE = new JpaLifecycleOptions();
@Override
@ -264,12 +289,14 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -264,12 +289,14 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
}
}
/**
* The lifecycle options used by libraries integrating into Hibernate ORM
* and that want a behavior closer to Spring's native behavior,
* such as Hibernate Search.
*/
private static class NativeLifecycleOptions implements BeanContainer.LifecycleOptions {
public static final NativeLifecycleOptions INSTANCE = new NativeLifecycleOptions();
@Override
@ -283,7 +310,9 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -283,7 +310,9 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
}
}
private static class IneffectiveBeanInstanceProducer implements BeanInstanceProducer {
public static final IneffectiveBeanInstanceProducer INSTANCE = new IneffectiveBeanInstanceProducer();
@Override
@ -297,8 +326,11 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -297,8 +326,11 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
}
}
private static class NoDefinitionInSpringContextTestBeanInstanceProducer implements BeanInstanceProducer {
private int unnamedInstantiationCount = 0;
private int namedInstantiationCount = 0;
@Override
@ -341,4 +373,5 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe @@ -341,4 +373,5 @@ public class HibernateNativeEntityManagerFactorySpringBeanContainerIntegrationTe
return namedInstantiationCount;
}
}
}

5
spring-orm/src/test/java/org/springframework/orm/jpa/hibernate/beans/NoDefinitionInSpringContextTestBean.java

@ -19,9 +19,8 @@ package org.springframework.orm.jpa.hibernate.beans; @@ -19,9 +19,8 @@ package org.springframework.orm.jpa.hibernate.beans;
public class NoDefinitionInSpringContextTestBean extends TestBean {
private NoDefinitionInSpringContextTestBean() {
throw new AssertionError(
"Unexpected call to the default constructor."
+ " Is Spring trying to instantiate this class by itself, even though it should delegate to the fallback producer?"
throw new AssertionError("Unexpected call to the default constructor. " +
"Is Spring trying to instantiate this class by itself, even though it should delegate to the fallback producer?"
);
}

2
spring-orm/src/test/resources/org/springframework/orm/jpa/hibernate/hibernate-manager-native.xml

@ -28,4 +28,6 @@ @@ -28,4 +28,6 @@
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean id="invalid" class="javax.persistence.AttributeConverter" lazy-init="true"/>
</beans>

Loading…
Cancel
Save