2014-01-07 4 views
2

Привет, У меня есть веб-приложение Java, использующее весну и спящий режим.bitronix- Не удалось найти текущую транзакцию JTA

У меня есть класс модели под названием Роль. Для всех классов модели есть общий GenericDao.java

public interface GenericDao<T>{ 
    public void insert(T transientInstance);  
    public T findById(Class<?> clazz, Serializable id); 
} 

GenericHibernateDao.java

@Repository 
public class GenericHibernateDao<T extends Serializable> 
implements GenericDao<T>{ 

    @Resource 
    protected SessionFactory sessionFactory; 

    @Override 
    public void insert(T transientInstance) { 
     sessionFactory.getCurrentSession().persist(transientInstance); 
    } 
     @SuppressWarnings("unchecked") 
    @Override 
    public T findById(Class<?> clazz, Serializable id) { 
     return (T) sessionFactory.getCurrentSession().get(clazz, id); 
     } 
} 

RoleService.java

public interface RoleService { 
    public void insert(Role role); 
    public Role findById(Integer id); 
} 

И имеет свою реализацию RoleServiceImpl. java

@Service 
public class RoleServiceImpl implements RoleService { 

    @Autowired 
    private GenericDao<Role> roleDao; 

    @Override 
    public void insert(Role role) { 
     roleDao.insert(role); 
    } 

    @Override 
    public Role findById(Integer id) { 
     return roleDao.findById(Role.class, id); 
    } 
} 

У меня есть контроллер, который вызывает эту findbyid methid и передавая значение - RegisterController.java

@Controller 
public class UserRegisterController { 

    @Autowired 
    public RoleService roleService; 

    @RequestMapping(value = "/register", method = RequestMethod.POST, consumes= MediaType.APPLICATION_JSON_VALUE) 
    @ResponseBody 
    public void registerUser(@RequestBody User user) 
    { 
     Role role=new Role(); 
     role=roleService.findById(1); 
     System.out.println("Saved"); 
    } 
} 

Наконец моя весна applicationContext.xml является

<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" 
     init-method="init" destroy-method="close"> 
     <property name="className" 
      value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> 
     <property name="uniqueName" value="ocr/DocumentDatabase" /> 
     <property name="minPoolSize" value="1" /> 
     <property name="maxPoolSize" value="5" /> 
     <property name="automaticEnlistingEnabled" value="true" /> 
     <property name="allowLocalTransactions" value="true" /> 
     <property name="useTmJoin" value="true" /> 
     <property name="shareTransactionConnections" value="true" /> 
     <property name="driverProperties"> 
      <props> 
       <prop key="url">${jdbc.url}</prop> 
       <prop key="user">${jdbc.username}</prop> 
       <prop key="password">${jdbc.password}</prop> 
      </props> 
     </property> 
    </bean> 
    <bean id="bitronixTransactionManager" factory-method="getTransactionManager" 
     class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig, dataSource" 
     destroy-method="shutdown" /> 

    <bean id="transactionManager" 
     class="org.springframework.transaction.jta.JtaTransactionManager"> 
     <property name="transactionManager" ref="bitronixTransactionManager" /> 
     <property name="userTransaction" ref="bitronixTransactionManager" /> 
    </bean> 
    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" 
     destroy-method="destroy"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="jtaTransactionManager" ref="transactionManager"/> 
     <property name="configLocation" value="classpath:hibernate.cfg.xml" /> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
       <prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop> 
      </props> 
     </property> 
    </bean> 

I запустите это приложение в tomcat. Он дает следующую ошибку.

SEVERE: Servlet.service() for servlet [myappdemo] in context with path [/myappdemo] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: Unable to locate current JTA transaction] with root cause 
org.hibernate.HibernateException: Unable to locate current JTA transaction 
    at org.hibernate.context.internal.JTASessionContext.currentSession(JTASessionContext.java:88) 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:90) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:980) 
    at com.myapp.myappdemo.dao.hibernate.GenericHibernateDao.findById(GenericHibernateDao.java:46) 
    at com.myapp.myappdemo.dao.hibernate.GenericHibernateDao.findById(GenericHibernateDao.java:15) 
    at com.myapp.myappdemo.service.impl.RoleServiceImpl.findById(RoleServiceImpl.java:38) 
    at com.myapp.myappdemo.web.UserRegisterController.registerUser(UserRegisterController.java:36) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 

Это происходит, когда я называю roleService.findById(1);

Почему его не случилось? И как я могу решить?

Я использую пружинный 3.2.1.RELEASE, Hibernate 4.2.0.Final, BTM 2.1.3

ответ

5

The SessionFactory настроен на использование JtaTransactionManager. Когда вы это делаете, hibernate достаточно умен, чтобы просмотреть текущие транзакционные ресурсы, чтобы найти сеанс.

Ваша конфигурация весны позволяет использовать аннотации для демаркации транзакций.

Ваш менеджер транзакций выглядит правильно настроенным.

Итак, все выглядит хорошо. Единственной недостающей частью являются транзакционные аннотации!

Просто добавьте @Transactional в вашем слое службы:

@Override 
@Transactional 
public Role findById(Integer id) { 
    return roleDao.findById(Role.class, id); 
} 

(вы также можете поместить эту аннотацию класса обслуживания)

+0

В классе службы я поставил. В то время я получаю «исключение тайм-аута транзакции» –

+1

Так что кажется, что «Невозможно найти текущую транзакцию JTA» исправлено.Пожалуйста, примите ответ и задайте еще один вопрос о срочной транзакции (если вы еще не решили его). Не забудьте опубликовать конфигурацию Spring (например, на этом посту + btmConfig bean) и стек. – ben75