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
相关产品推荐
相关产品推荐

