2017-11-05 9 views
0

遅延ロードされたプロパティList<OrderItem>を含むOrderクラスがあります。私はそれを怠惰に保つ必要があります。 1の場合 は、私は春JPARepository経由ですべての注文をロードしています:遅延読み込みとHibernate.initialize()の問題。

@org.springframework.transaction.annotation.Transactional; 
protected void doThingsWithOrderItems() { 
    List<Order> orders = orderRepository.findAll(); 
    for (Order order : orders) { 
     Hibernate.initialize(orders.getOrderItems()); 
     // do things with orders and their order items 
    } 
} 

以前の方法は、私の問題は私が得ることである

@Configurationクラスの@PostConstruct方法で呼び出されます。

ERROR 15580 --- [   main] o.s.boot.SpringApplication    : Application startup failed 

org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at com.lh.application.MyApplication.main(MyApplication.java:10) [classes/:na] 
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat 
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:123) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:84) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:554) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:179) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:164) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:134) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    ... 8 common frames omitted 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initSettingsConfigurator': Invocation of init method failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.lh.application.entity.Order.OrderItems, could not initialize proxy - no Session 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:234) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:215) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:91) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:79) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:241) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:228) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:89) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:213) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:55) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE] 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196) ~[tomcat-embed-core-8.5.20.jar:8.5.20] 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.5.20.jar:8.5.20] 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1419) ~[tomcat-embed-core-8.5.20.jar:8.5.20] 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) ~[tomcat-embed-core-8.5.20.jar:8.5.20] 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_91] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_91] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_91] 
    at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_91] 
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.lh.application.entity.Order.orderItems, could not initialize proxy - no Session 
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:587) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:204) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:566) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:135) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:163) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at com.lh.application.entity.Order.doThingsWithOrderItem(Order.java:206) ~[classes/:na] 
    at com.lh.application.config.InitSettingsConfigurator.doThingsWithOrderItems(InitSettingsConfigurator.java:169) ~[classes/:na] 
    at com.lh.application.config.InitSettingsConfigurator.init(InitSettingsConfigurator.java:159) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91] 
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91] 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE] 
    ... 34 common frames omitted 

私は@Transactionalメソッドの中にあります。以前の関連する質問と回答によれば、私の解決策は動作すると期待しています。どうしましたか?

+0

あなたはおそらく実際に取引方法の中にいません。おそらく、あなたはトランザクション用のSpring Beanをインジェクトしていなかったので、代わりにnewを使用して作成したからです。関連するコードを投稿してください。また、完全なスタックトレースをコードとして投稿してください。 –

+0

@JBNizet OP updated – Manu

+2

Beanの構築中にトランザクションメソッドを呼び出そうとしているようです。この回答はhttps://stackoverflow.com/a/18790494/1654233に役立ちます。 – yegodm

答えて

1

doThingsWithOrderItemsthisという参照を呼び出している可能性があります。これは、基本的にプロキシされていないオブジェクトに対するメソッドの呼び出しです。春のフレームワークにおける自己注射の前バージョン4.3に動作しない可能性があること

@Component 
public class YourBean { 

    @Autowire 
    private YourBean yourBean; 

    @PostConstruct 
    private init(){ 
     yourBean.doThingsWithOrderItems(); 
    } 

    @org.springframework.transaction.annotation.Transactional; 
    public void doThingsWithOrderItems() { 
     List<Order> orders = orderRepository.findAll(); 
     for (Order order : orders) { 
      Hibernate.initialize(orders.getOrderItems()); 
      // do things with orders and their order items 
     } 
    } 
} 

注:春はあなたが、いわゆるself-injectionパターンを使用するプロキシを作成するために。

この問題を解決するもう1つの方法(おそらく望ましい方法)は、トランザクションメソッドを分離されたbeanに抽出することです。ほとんどの場合、テストするのが簡単な、より洗練されたコードを提供します(Mockitoの@Spyを使って部分的なモックを作るよりも、依存関係をモックするほうがずっと簡単で良い)。

+0

initメソッドでこのメソッドを呼び出す別のBeanがあれば、より明確になります。 –

+0

はい、同意します。さらに、別のBeanを擬似するほうが簡単なので、もっとテストできるでしょう。私の答えが更新されます。 –

関連する問題