2016-11-29 1 views
0

Springアプリケーションバージョン4.3.3.RELEASE Hibernate 5.1.0.FinalとJava 8を使用しています このアプリケーションには、Javaシッククライアントアプリケーションにサービスを公開するrmiインタフェースがあります。このアプリケーションでは、Spring Restful Webservicesも公開されています。 私たちの問題を引き起こしているサービスは、rmiサービスとして安らかなwsとして公開されています。 RMIとしてのサービスの呼び出しは素晴らしいですが、安らかなwsを呼び出すと、以下に示すようにjavax.persistence.TransactionRequiredExceptionが発生します。Spring rmiサービスは正常に機能しますが、安心して動作しません

は、私はここにこの問題への答えを見つけたと思ったが、私は物事が右のように見えることはできません。

@Transactional(propagation = Propagation.REQUIRES_NEW) 

しかしI: Spring @Transactional not working

We'weは次のように、多くの異なるものを試してみましたここでの問題は、私が2つのspring-configファイルを持っていて、springrest-config.xmlに適切なものを定義していないことです。

誰もこれを解決する方法を知っていますか?ここ

はDAO方法であって、ここで

@Override 
    public void deleteFormReplyForInvitation(Long id) { 

     try { 
      entityManager.createQuery("DELETE FROM FormReply where id = " + id).executeUpdate(); 


     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

は、サービスコードである:ここ

@Override 
@Transactional 
public String withdrawConsent(final String username, final Patient patient, final String method) { 

try { 
    List<Invitation> invitations = invitationService.getInvitationsForPatient(patient); 
    for (Invitation invitation : invitations) { 
     if (invitation.getFormReply() != null) { 
      formReplyService.deleteFormReply(invitation.getFormReply().getId()); 
     } 
     if (!invitation.getReminders().isEmpty()) { 
      reminderService.deleteReminders(invitation); 
     } 
     invitationService.deleteInvitation(invitation.getId()); 
    } 

    eventlogService.deleteEventlog(patient); 


    EntryKind entryKind = entryKindService.getEntryKind(1); 
    eventlogService.addEventlog(patient, eventlogDataDeleted, entryKind, true, username); 

    addConsent(patient, method, username); 

    patient.setActive(false); 
    patientService.saveOrUpdatePatient(patient); 

    return "OK"; 


} catch (Exception e) { 
    logger.error("Feil oppstått i withdrawConsent.", e); 
    return "ERROR"; 

} 
} 

@Override 
    @Transactional 
    public String withdrawConsent(final String birthNumber, final String programCode) { 
     String encryptedPNR = encryptionService.encryptDBQ(birthNumber); 
     Cancertype cancertype = cancertypeService.getCancertypeByCode(programCode); 
     Patient aPatient = patientService.getPatient(encryptedPNR, cancertype); 

     return withdrawConsent("WebService", aPatient, "Webservice"); 
    } 

は休止コントローラである:ここ

@RequestMapping(value = "/withdrawconsent", method = RequestMethod.GET) 
    @Transactional 
    String withdrawConsent(@RequestParam("programcode") final String programcode, @RequestParam("birthnumber") final String birthnumber) throws CancertypeException { 
     return consentService.withdrawConsent(birthnumber, programcode); 
    } 

はスプリング設定です。 xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://camel.apache.org/schema/spring/v2.15" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" 

     xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-4.1.xsd 
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" 
     default-autowire="byName"> 


    <!-- Root Context: defines shared resources visible to all other web components --> 
    <context:component-scan base-package="net.krg.proms" /> 
    <context:annotation-config /> 



    <!-- Define all property files here. Values will be available in all other spring config files. --> 
    <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
     <property name="locations"> 
      <list> 
       <value>classpath:db.properties</value> 
       <value>classpath:system.properties</value> 
      </list> 
     </property> 
    </bean> 

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" name="EntityManagerFactory"> 
     <property name="packagesToScan" value="net.krg.proms" /> 
     <property name="persistenceUnitName" value="proms"></property> 
     <property name="dataSource" ref="dataSource"></property> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="${db.show_sql}" /> 
       <property name="generateDdl" value="false" /> 
       <property name="databasePlatform" value="${db.dialect}" /> 
      </bean> 
     </property> 

    </bean> 

<!-- Values are defined in db.properties --> 
<!--<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">--> 
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${db.driver}" /> 
    <property name="url" value="${db.url}" /> 
    <property name="username" value="${db.username}" /> 
    <property name="password" value="${db.password}" /> 
</bean> 

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="packagesToScan"> 
     <list> 
      <value>net.krg.proms.domain.proms</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${db.dialect}</prop> 
      <prop key="hibernate.show_sql">${db.show_sql}</prop> 
      <prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl.auto}</prop> 
     </props> 

    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" name="TransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"></property> 
    <property name="persistenceUnitName" value="proms"/> 
</bean> 


<bean id="entityManagerFactory2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" name="EntityManagerFactory2"> 
    <property name="packagesToScan" value="net.krg.proms.domain.hdb" /> 
    <property name="persistenceUnitName" value="hdb"></property> 
    <property name="dataSource" ref="dataSource2"></property> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="showSql" value="${db.hdb.show_sql}" /> 
      <property name="generateDdl" value="false" /> 
      <property name="databasePlatform" value="${db.hdb.dialect}" /> 
     </bean> 
    </property> 

</bean> 
<!-- Values are defined in db.properties --> 
<!--<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">--> 
<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${db.hdb.driver}" /> 
    <property name="url" value="${db.hdb.url}" /> 
    <property name="username" value="${db.hdb.username}" /> 
    <property name="password" value="${db.hdb.password}" /> 
</bean> 

<bean id="txManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource2"/> 
</bean> 

<bean id="sessionFactory2" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource2"/> 
    <property name="packagesToScan"> 
     <list> 
      <value>net.krg.proms.domain.hdb</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${db.hdb.dialect}</prop> 
      <prop key="hibernate.show_sql">${db.hdb.show_sql}</prop> 
      <!-- <prop key="hibernate.hbm2ddl.auto">${db.hdb.hbm2ddl.auto}</prop>--> 
     </props> 

    </property> 
</bean> 

<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager" name="TransactionManager2"> 
    <property name="entityManagerFactory" ref="entityManagerFactory2"></property> 
    <property name="persistenceUnitName" value="hdb"/> 
</bean> 

<tx:annotation-driven /> 
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 


<!--RMI starts Here--> 
<!--this is the only bean that should be use expose all the needed RMI sercices which GUI will consume--> 
<bean id="rmiServices" class="net.krg.proms.services.RMIServiceImpl"/> 
<bean id="remoting_MessageSpecificationService_Proxy_Exporter" class="org.springframework.remoting.rmi.RmiServiceExporter"> 
    <property name="service" ref="rmiServices"/> 
    <property name="serviceInterface" value="net.krg.proms.rmiInterfaces.RMIServices"/> 
    <property name="serviceName" value="rmiServices"/> 
    <property name="registryPort" value="10998"/> 
    <property name="alwaysCreateRegistry" value="false"/> 
</bean> 
<!--RMI end here--> 


<!--include camel configuraiton here --> 
<!--load camel context--> 
<import resource="camel-config.xml"/> 
0123ここで

は、ばね安らかWSのための設定である:ここで

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation=" http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-4.1.xsd 
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> 

    <mvc:annotation-driven/> 
    <context:component-scan base-package="net.krg.proms.services" /> 
    <context:annotation-config></context:annotation-config> 
</beans> 

は、web.xmlです:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app metadata-complete="true" 
     xmlns="http://java.sun.com/xml/ns/javaee" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
      version="2.5"> 


    <listener> 
     <listener-class> 
      org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath*:/spring-config.xml</param-value> 
    </context-param> 
<!----> 

    <!--ws--> 
    <servlet> 
     <servlet-name>springrest</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/WEB-INF/springrest-servlet.xml</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>springrest</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 


</web-app> 

私たちは私のWebサービスを呼び出すために使用するURL:S http://xxx-xxx-xxx:8080/proms-services-1.0-SNAPSHOT/withdrawconsent?birthnumber=01016512345&programcode=PR

rest-wsを呼び出すときのスタックトレース:

*36860 [http-nio-8080-exec-34] ERROR net.krg.proms.services.impl.ConsentServiceImpl - Feil oppst?tt i withdrawConsent. 
java.lang.RuntimeException: javax.persistence.TransactionRequiredException: Executing an update/delete query 
     at net.krg.proms.dao.impl.FormReplyDaoImpl.deleteFormReplyForInvitation(FormReplyDaoImpl.java:61) 
     at net.krg.proms.services.impl.FormReplyServiceImpl.deleteFormReply(FormReplyServiceImpl.java:36) 
     at net.krg.proms.services.impl.ConsentServiceImpl.withdrawConsent(ConsentServiceImpl.java:72) 
     at net.krg.proms.services.impl.ConsentServiceImpl.withdrawConsent(ConsentServiceImpl.java:110) 
     at net.krg.proms.services.ws.krgcommon.PatientInfoController.withdrawConsent(PatientInfoController.java:77) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:498) 
     at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)* 
+0

コンポーネントのスキャンのために、2つのサービスインスタンスが作成されています。あなたのサーブレットはWeb関連のBean( '@ Controller')のみをスキャンし、' ContextLoaderListener'によって読み込まれる残りのものは無視します。これで、2つのインスタンスが親コンテキスト( 'ContextLoaderListener')からのものであり、間違ったものが' DispatcherServlet'の中のものです。 –

+0

ありがとう@ M-デニウム、問題を解決しました。これは、新しい問題(コレクションを2つのオープンセッションに関連付ける違法な試み)につながりました。エンティティの更新の代わりにマージを使用して解決しました。 –

答えて

0

私が知る限り、トランザクション管理はサービス層にのみ属し、永続性コントローラではありません。多分、それはrmi経由で@Transactionメソッドを公開している間、何らかの矛盾を引き起こします。

関連する問題