Hi,
I am trying to setup Spring to work with CMT (container managed transactions)
Here is my setup :
applicationContext.xml
persistemce.xmlCode:<?xml version="1.0" encoding="UTF-8"?> <beans > <!-- Skipped schema an sstuff --> <context:annotation-config /> <context:component-scan base-package="com.aa, com.xxx,com.yyy" /> <tx:jta-transaction-manager /> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="KATPU" /> </bean> </beans>
AdminService.javaCode:<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="KATPU" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/jdbc/DBPersister</jta-data-source> <class>com.aa.class1</class> <properties> <!-- This is VERY important !!! --> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> <property name="hibernate.id.new_generator_mappings" value="true"/> </properties> </persistence-unit> </persistence>
userDaoCode:package com.mypack; //Skip imports @Service("adminService") @Transactional public class AdminService { private UserDao dao; @Autowired public void setDao(UserDao dao) { this.dao = dao; } public User save(User user){ User u = dao.update(user); User u1 = new User(); // create dummy user u1.setId(9); // this is incorrect on purpouse! u1.setName("sdlfuhsoixkfsd"); u1.setPassword("1"); dao.update(u1); /*if (true) throw new RollbackException();*/ return u; } }
What i am basicly doing is to persist one entity, and intentionaly try to persists one more "bad" entity.Code:package com.dao; import java.util.List; //skip import @Repository public class UserDao implements GenericDao<User, Long>{ @PersistenceContext(unitName = Constants.PERSISTENCE_UNIT) private EntityManager em; @Override public User update(User entity) { return em.merge(entity); } //skip rest }
The idea was to see if the transaction is running.
The problem is that when the second persist fails, the fisrt entity is persisted in the database.
This should not happen IMO becouse the srevice is annotated as @Transactional
One could reproduce this if the second entity fails on validation (for example @NotEmpty)
Second test :
AdminService.java
What i do here is the same except i manualy throw RollbackException.Code:package com.mypack; //Skip imports @Service("adminService") @Transactional public class AdminService { private UserDao dao; @Autowired public void setDao(UserDao dao) { this.dao = dao; } public User save(User user){ User u = dao.update(user); User u1 = new User(); // create dummy user u1.setId(9); // this is incorrect on purpouse! u1.setName("sdlfuhsoixkfsd"); u1.setPassword("1"); dao.update(u1); if (true) throw new RollbackException(); return u; } }
This work as expected. Both records are not in the database
Also note that in service i can call to TransactionSynchronizationManager.isActualTransact ionActive()
and that returns TRUE .
I guess i am doing something wrong here .
I just can't see what .
Any help is appreciated.
Here is some app startup logs which seem ok to me :
Code:17:14:19,621 INFO [org.hibernate.service.jdbc.connections.internal.ConnectionProviderInitiator] (MSC service thread 1-1) HHH000130: Instantiating explicit connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider 17:14:19,642 INFO [org.hibernate.dialect.Dialect] (MSC service thread 1-1) HHH000400: Using dialect: org.hibernate.dialect.InformixDialect 17:14:19,644 INFO [org.hibernate.engine.jdbc.internal.LobCreatorBuilder] (MSC service thread 1-1) HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4 17:14:19,647 INFO [org.hibernate.engine.transaction.internal.TransactionFactoryInitiator] (MSC service thread 1-1) HHH000268: Transaction strategy: org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory 17:14:19,649 INFO [org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory] (MSC service thread 1-1) HHH000397: Using ASTQueryTranslatorFactory 17:14:19,994 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] (MSC service thread 1-1) Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@607c42: defining beans [messageSource,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,permissionDao,roleDao,userDao,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0,adminService,userDetailsService,myDataSource,org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#1,entityManagerFactory,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,org.springframework.security.filterChains,org.springframework.security.filterChainProxy,org.springframework.security.web.DefaultSecurityFilterChain#0,org.springframework.security.web.DefaultSecurityFilterChain#1,org.springframework.security.web.DefaultSecurityFilterChain#2,org.springframework.security.web.DefaultSecurityFilterChain#3,org.springframework.security.web.DefaultSecurityFilterChain#4,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.web.PortResolverImpl#0,org.springframework.security.config.authentication.AuthenticationManagerFactoryBean#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.authentication.http://www.BasicAuthenticationEntryP...areProcessor]; root of factory hierarchy 17:14:20,125 INFO [org.springframework.transaction.jta.JtaTransactionManager] (MSC service thread 1-1) Using JTA UserTransaction: org.jboss.tm.usertx.client.ServerVMClientUserTransaction@108294e 17:14:20,127 INFO [org.springframework.transaction.jta.JtaTransactionManager] (MSC service thread 1-1) Using JTA TransactionManager: com.arjuna.ats.jbossatx.jta.TransactionManagerDelegate@1dd6a83 17:14:20,128 INFO [org.springframework.transaction.jta.JtaTransactionManager] (MSC service thread 1-1) Using JTA TransactionSynchronizationRegistry: com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionSynchronizationRegistryImple@1f46be2


Reply With Quote