Any help with this would be greatly appreciated. Iam using Spring, Jetty (Eclipse Jetty Plugin). It seems that the declarative transaction management @Transactional does not work.
It is confirmed that this does not work in two ways: 1. After calling the method, the newly created entity is not dumped to the database. 2. TransactionSynchronizationManager.isActualTransactionActive (); returns false
Note that the method described below is different from the @Controller class when invoking an HTTP request ultimately calls this save method. The controller class does not implement any interfaces. Actual code:
@Transactional(propagation = Propagation.REQUIRES_NEW) public void save(PERule peRule) { boolean inTransaction = TransactionSynchronizationManager.isActualTransactionActive(); peRuleDAOImpl.persist(peRule); }
The absence of a transaction is also confirmed by the output of the log:
DEBUG: org.hibernate.internal.SessionImpl - Opened session at timestamp: 13762325621 DEBUG: org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl - Skipping JTA sync registration due to auto join checking DEBUG: org.hibernate.ejb.AbstractEntityManagerImpl - Looking for a JTA transaction to join DEBUG: org.hibernate.ejb.AbstractEntityManagerImpl - Unable to join JTA transaction DEBUG: org.hibernate.event.internal.AbstractSaveEventListener - Delaying identity-insert due to no transaction in progress
However, when I programmatically determine the explicit boundaries of transactions and commit the transaction, the object is painted over to the database. For instance:
@Resource private PlatformTransactionManager txManager; private void save(PERule peRule) { DefaultTransactionDefinition def = new DefaultTransactionDefinition(); TransactionStatus status = txManager.getTransaction(def); def.setName("SomeTxName"); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); try { peRuleDAOImpl.persist(peRule); } catch (Exception ex) { txManager.rollback(status); } txManager.commit(status); }
Therefore, this does not seem to be a problem with the way I defined my transactionManager, since it can be injected into an object as defined above.
ContextConfig: root-context.xml
<aop:aspectj-autoproxy /> <context:annotation-config /> <context:component-scan base-package="org.springframework.samples.mvc, com.project.*" /> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>/WEB-INF/spring/proddatabase.properties</value> </property> </bean> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/myds" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="persistenceUnitName" value="EconDatesDB" /> <property name="persistenceXmlLocation" value="/WEB-INF/spring/jpa-prod-persistence.xml" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="false" /> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.format_sql">false </prop> <prop key="hibernate.use_sql_comments">false </prop> <prop key="hibernate.generate_statistics">false </prop> <prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory </prop> <prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup </prop> </props> </property> </bean> <tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="atomikosTransactionManager" /> <property name="userTransaction" ref="atomikosUserTransaction" /> </bean> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <property name="transactionTimeout" value="300" /> </bean> <bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <property name="forceShutdown" value="false" /> <property name="transactionTimeout" value="300" /> </bean> <mvc:annotation-driven /> <beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <beans:property name="formatters"> <beans:bean class="org.springframework.samples.mvc.convert.MaskFormatAnnotationFormatterFactory" /> </beans:property> </beans:bean> <beans:import resource="/appServlet/controllers.xml" />
servlet context:
<resources mapping="/resources/**" location="/resources/" /> <resources mapping="/sharedResources/**" location="/parkingEngine/resources/" /> <beans:bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="order" value="1" /> <beans:property name="prefix" value="" /> <beans:property name="suffix" value=".jsp" /> </beans:bean>
web.xml:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
pom.xml related dependencies:
<dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.10</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.10</version> </dependency>
I also tried the following tx variations: annotation-driven in my root context. xml:
<tx:annotation-driven mode="aspectj" proxy-target-class="true" transaction-manager="transactionManager"/> <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/> <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/> <tx:annotation-driven />