2011-03-07 88 views
2

在以下架構春天@Transactional - javax.persistence.TransactionRequiredException

控制器 - >服務 - > DAO我試圖使服務操作@Transactional

在我UserService.fooFunction()我叫

Entity e = dao.find(key) 
e.setProperty(something) 
dao.update(e) 

在末dao.update(e)中有

em.flush() //EntityManager obtained by @PersistenceContext annotation (injected by spring IoC) 

調用flush()會拋出的PersistenceException:

javax.persistence.TransactionRequiredException No externally managed transaction is currently active for this thread 
    at org.eclipse.persistence.internal.jpa.transaction.JTATransactionWrapper.throwCheckTransactionFailedException(JTATransactionWrapper.java:86) 

我的想法所剩無幾我做了什麼錯了,任何幫助,將不勝感激:)

您可以在下面找到我的配置大塊:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="persistenceUnitName" value="myPU" /> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter" id="eclipselinkVendorAdapter"> 
     .. 
     </bean> 
    </property> 

</bean> 

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 

</bean> 
<tx:annotation-driven transaction-manager="transactionManager"/> 

AOP部分:

<aop:config> 

    <aop:pointcut id="userServiceOperation" 
     expression="execution(* org.mypackage.UserServiceImpl.*(..))"/> 

    <aop:advisor pointcut-ref="userServiceOperation" advice-ref="txUserServiceAdvice"/> 

</aop:config> 

<tx:advice id="txUserServiceAdvice"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true" propagation="REQUIRES_NEW"/> 
     <tx:method name="update*" read-only="false" propagation="REQUIRES_NEW"/> 
     <tx:method name="*" propagation="REQUIRES_NEW"/> 
    </tx:attributes> 
</tx:advice> 

沒有事務註解都存在。當我部署春應用程序可以看到

[<date>] DEBUG support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 
[<date>] DEBUG interceptor.NameMatchTransactionAttributeSource: Adding transactional method [get*] with attribute [PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT,readOnly] 
[<date>] DEBUG interceptor.NameMatchTransactionAttributeSource: Adding transactional method [update*] with attribute [PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT] 
[<date>] DEBUG interceptor.NameMatchTransactionAttributeSource: Adding transactional method [*] with attribute [PROPAGATION_MANDATORY,ISOLATION_DEFAULT] 

回答

4

關鍵的問題是在這裏

TX:註解驅動只​​查找 @Transactional在它的定義相同 應用程序上下文豆 這意味着,如果您將 放入 WebApplicationContext的 DispatcherServlet中,它僅在您的 控制器中檢查 @Transactional bean,而不是您的服務。 有關更多 信息,請參見第15.2節「 DispatcherServlet」。

把我同一個應用程序上下文組件掃描服務的問題解決了:)

0

你宣佈JtaTransactionManager爲您的事務管理器。你確定你的程序運行在支持JTA的環境中,比如成熟的應用服務器(JBoss,WebSphere,WebLogic等)?

如果沒有JTA環境中,你需要使用JPATransactionManager代替:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 
+0

是 - 我正在運行的Sun的GlassFish應用服務器上的這個程序。我認爲我的問題解決了:)謝謝你的回覆! – Jan 2011-03-07 14:56:27