У нас есть устаревшее приложение Spring-ws для конфигурации на основе XML, которое содержит endpointInterceptors, для которых DAO вводятся для получения конфигурации из базы данных. Эти DAO имеют вложенную сессию спящего режима.Перехватчики Spring WS с введенным DAO @Transactional не работают
Когда мы обновили до весны 4.2.0.RELEASE (с весны 3.2.5.RELEASE) и пружины с 2.2.1.RELEASE (от spring-ws 2.1.4.RELEASE) Я заметил, что DAO был не прокси-объект, и казалось, что intercetor собирался в класс AnnotationActionEndpointMapping вместо класса PayloadRootAnnotationMethodEndpointMapping.
Поэтому я создал пример с весенней загрузкой 1.3.0.RELEASE, в котором излагается наше устаревшее приложение, и проблема очевидна как в конфигурации базы данных XML, так и в форме аннотации. Обратите внимание, что в примере существует аннотация @EnableTransactionManagement и существует в устаревшем приложении.
Если вы отметили контекст приложения или @EnableWS из объекта @Congiuration, тогда DAO был прокси-объектом, перехватчик, казалось, шел к правильному пути (например, PayloadRootAnnotationMethodEndpointMapping), а модульный тест работал без ошибка транзакции.
StackTrace when или EnableWS не закомментирован.
org.springframework.ws.soap.client.SoapFaultClientException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378)
at hello.ApplicationTests.testSendAndReceive(ApplicationTests.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Извлечение конфигурации XML, который вызывает выше исключение:
<sws:annotation-driven>
<sws:interceptors>
<ref bean="loggingInterceptorAU"/>
</sws:interceptors>
<bean id="loggingInterceptorAU" class="hello.interceptor.LoggingEndpointInterceptor"/>
Извлечение конфигурации аннотаций, который вызывает выше исключение:
@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
@Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
@Bean(name = "countries")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("CountriesPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://spring.io/guides/gs-producing-web-service");
wsdl11Definition.setSchema(countriesSchema);
return wsdl11Definition;
}
@Bean
public XsdSchema countriesSchema() {
return new SimpleXsdSchema(new ClassPathResource("countries.xsd"));
}
/**
* Declaring the loggingInterceptor.
* @return the new logging interceptor.
*/
@Bean
public LoggingEndpointInterceptor loggingInterceptor() {
LoggingEndpointInterceptor loggingEndpointInterceptor = new LoggingEndpointInterceptor();
return loggingEndpointInterceptor;
}
/**
* Adds interceptors.
* @param interceptors
*/
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
// if these rows are uncommented
// and payloadRootAnnotationMethodEndpointMapping method is commented you get
// Error: SoapFaultClientException: Could not obtain transaction-synchronized Session for current thread
interceptors.add(loggingInterceptor());
super.addInterceptors(interceptors);
}
/**
* Spring Boot with Plain Hibernate
* @see {https://github.com/mdeinum/samples/tree/master/spring-boot-plain-hibernate}
*
* Need to also set within application.properties.
* spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext
* @return
*/
@Bean(name="sessionFactory")
public HibernateJpaSessionFactoryBean sessionFactory() {
return new HibernateJpaSessionFactoryBean();
}
}
После более внимательном макияжа of AnnotationActionEndpointMapping я заметил, что он реализует BeanPostProcessor. Весенний doco http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html предполагает, что «... Поскольку автопроксирование AOP реализовано как сам BeanPostProcessor, ни BeanPostProcessors, ни bean-компоненты, которые они ссылаются напрямую, не имеют права на автоматическое проксирование и, следовательно, не имеют аспектов, вплетенных в них». и поэтому я понимаю, что @Transactional не будет работать.
public class AnnotationActionEndpointMapping extends AbstractActionMethodEndpointMapping implements BeanPostProcessor
Мои вопросы: * что изменилось, что вызвало весной-WS-перехватчики, которые будут отображаться по умолчанию в классе AnnotationActionEndpointMapping? * В соответствии с весенней документацией рекомендуется использовать как и/или @EnableWs, так и метод addInterceptors. Есть ли какое-либо влияние, если закомментировано в нашем устаревшем приложении?
Пожалуйста, обратите внимание, у нас есть перехватчики, которые вызываются только для определенных запросов с использованием следующих, и мы не хотим, чтобы specicially создать PayloadRootAnnotationMethodEndpointMapping боб со списком перехватчиков, чтобы преодолеть эту проблему:
<sws:interceptors>
<sws:payloadRoot localPart="TestRequest" namespaceUri="http://www.test.com/test/request/1.0">
...
Это все еще проблема. Кто-нибудь сталкивался с той же проблемой? Я считаю, что следующее изменение [Spring] (https://jira.spring.io/browse/SWS-874) могло вызвать эту проблему. В нашем унаследованном приложении мы все еще комментируем xml config __sws: annotation-driven__ и хотели бы, чтобы кто-то из весны проверил вышеупомянутую проблему. –
Я подал билет на весну jira [SWS-974] (https://jira.spring.io/browse/SWS-974), чтобы надеяться решить эту проблему. –
можно рассматривать как некроповую, но точно так же, как и предложение, пожалуйста, проверьте проверку компонентов. убедитесь, что класс, аннотированный аннотацией конечных точек, является частью, проверенной ТОЛЬКО сервлером webservice, указанным в web.xml, а также не // только с помощью проверки компонента, которую вы выполняете, например, вашего корневого приложенияContext.xml .. Я предлагаю это, потому что, например, если контроллеры сканируются как applicationContext, так и сервлетом, транзакционная аннотация не будет работать, поэтому у вас может быть одна и та же проблема, только контекстуализированная с конечными точками вместо контроллеров :) – witchedwiz