You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Resteasy与Spring集成JTA事务遇异常,求正确实现方案

Resteasy与Spring集成及JTA事务AOP配置问题

项目结构

com.example.dao
   - UserDAO
com.example.daoimpl
   - UserDAOImpl
com.example.services.api
   - EmployeeApi
com.example.services.api.impl
   - EmployeeApiImpl

AOP配置(aop.xml)

<tx:advice id="txServiceAdvice" transaction-manager="txManager">
    <tx:attributes>
        <!-- 所有以search/view/get/is开头的方法为只读 -->
        <tx:method name="search*" read-only="true"/>
        <tx:method name="view*" read-only="true"/>
        <tx:method name="get*" read-only="true"/>
        <tx:method name="is*" read-only="true"/>

        <!-- 其他方法需要事务 -->
        <tx:method name="*" read-only="false"
            propagation="REQUIRED"
            isolation="READ_COMMITTED"
            rollback-for="RuntimeException"
            no-rollback-for="ServiceException" />

    </tx:attributes>
</tx:advice>

   <aop:config>
      <aop:pointcut id="restApiPointcut" expression="execution(* com.example.services.*.*(..))"/>
      <aop:advisor advice-ref="txServiceAdvice" pointcut-ref="restApiPointcut"/>
   </aop:config>

初始实现及错误

通过ApplicationContextAware方式集成Resteasy与Spring,最初的EmployeeApiImpl实现如下:

@Path("/requests")
@Component
public class EmployeeApiImpl {


   @GET
   @Path("/{id}")
   @Produces({MediaType.APPLICATION_JSON})
   @Transactional
   public int findUserCountByEmpId(@PathParam(value = "id") Long id) throws ServiceException {
      UserDAO userDAO= SpringApplicationContext.getBean("UserDAO", UserDAOImpl.class);
      return userDAO.findCountById(id);
   }

}

调用API时出现错误:

14:59:27,477 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /example-fe-war/api/requests/170: org.jboss.resteasy.spi.UnhandledException: org.hibernate.HibernateException: Unable to locate current JTA transaction
        ...(省略部分栈信息)
Caused by: org.hibernate.HibernateException: Unable to locate current JTA transaction
        ...(省略部分栈信息)

调整后代码及新错误

添加Service层后,代码调整为:

EmployeeApiImpl:

@Path("/requests")
public class EmployeeApiImpl   {

   @GET
   @Path("/{id}")
   @Produces({MediaType.APPLICATION_JSON})
   public int findUserCountByEmpId(@PathParam(value = "id") Long id) throws ServiceException {
      ExampleService exampleService = SpringApplicationContext.getBean("exampleService", ExampleService.class);
      return exampleService.findUserCountByEmpId(id);
   }

}

ExampleService:

public class ExampleService {


   @Transactional
   public int findUserCountByEmpId(Long id) throws ServiceException {
     UserDAO userDAO= SpringApplicationContext.getBean("UserDAO", UserDAOImpl.class);
      return userDAO.findCountById(id);
   }
}

此时调用API出现新错误:

13:17:02,254 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /example-fe-war/api/requests/170: org.jboss.resteasy.spi.UnhandledException: javax.ws.rs.ProcessingException: RESTEASY008205: JSON Binding serialization error javax.json.bind.JsonbException: Unable to serialize property 'Address' from com.example.entities.User
        ...(省略部分栈信息)
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
        ...(省略部分栈信息)

核心问题

Spring的事务AOP配置对普通Spring类有效,但对标注了@Path和@Component的类无效。请问如何正确集成Resteasy与Spring并实现JTA事务,让userDAO.findCountById方法能在正确的事务环境中执行?


内容的提问来源于stack exchange,提问作者Abhishek Kotalwar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 23:40:34