Spring transactional context doesn't persist data
Solution 1
solved my problem using
org.springframework.orm.jpa.JpaTransactionManager
so your bean should be
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />
hope this work!
Solution 2
In the version of the code that uses the JPA entity manager. Try adding an em.flush() after the em.persist() - all em.persist() does is to attach the entity to the persistence context. The entity is not 'persisted' at that point.
You should not need the em.flush() - but give it a try to see if it helps.
When the transaction ends then the persistence context should automatically be flushed (written to the db).
I have to say you've got quite a complicated setup here - you might need some trial & error to narrow it down. Adding JTA into the mix might not help matters - you could try with 'resource local' in Spring until you get it working. Are there any errors in the logs ?
Comments
-
Arek Woźniak almost 2 years
I know that my problem is a common problem, but I've checked a lot of questions here, checked Spring documentation and I really don't know what I am doing wrong. My problem: I've got a Spring WebFlow project using JPA (implementation: OpenJPA + MySQL database). I use Spring ORM to inject EntityManager (by @PersistenceContext annotation) to my simple RegisterDAO. I have configured GlassFishs (which I am using) connection pools for using MySQL and everything works - I can work with my database, but when I am persisting something - nothing happens (data are not persist to database). I know that problem is with transactional context which I use. I read the documentation of Spring Transaction Management and follow the configuration steps in this documentation. This is my applicationContext.xml:
<?xml version="1.0" encoding="windows-1250"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"> <jee:jndi-lookup id="entityManagerFactory" jndi-name="myPersistenceUnit"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="registerDaoImpl" class="umk.dumont.db.dao.RegisterDAO" /> <bean id="registerModel" class="umk.dumont.models.RegisterFormModel"> <property name="registerDAO" ref="registerDaoImpl" /> </bean> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="registerModelOperation" expression="execution(* umk.dumont.models.RegisterFormModel.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="registerModelOperation"/> </aop:config> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> </beans>
As you can see I am injecting RegisterDAO into my RegisterFormModel, which contains my business logic for validating register form data and eventually adding user to database. Validating works fine, the problem occurs when I am trying to add new user. Here is the code:
package umk.dumont.models; ... public class RegisterFormModel implements Serializable { private String login; private String password; private String email; @Autowired private RegisterDAO registerDAO = null; ... public boolean addUser() { MyUser user = new MyUser(); user.setLogin(login); user.setPassword(password); user.setEmail(email); return registerDAO.insertUserIntoDB(user) == 0 ? true : false; } ... }
RegisterDAO:
public class RegisterDAO implements RegisterDAOInterface, Serializable { private EntityManager em; @PersistenceContext public void setEm(EntityManager em) { this.em = em; } ... public int insertUserIntoDB(MyUser user) { int result = -4; try { em.persist(user); result = 0; } catch(Exception ex) { ex.printStackTrace(); result = -4; } finally { return result; } } ... }
I have also tried with @Transactional annotation. I configured spring applicationContext.xml like this:
<?xml version="1.0" encoding="windows-1250"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd"> <jee:jndi-lookup id="entityManagerFactory" jndi-name="myPersistenceUnit"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> <bean id="registerDaoImpl" class="umk.dumont.db.dao.RegisterDAO" /> <bean id="registerModel" class="umk.dumont.models.RegisterFormModel"> <property name="registerDAO" ref="registerDaoImpl" /> </bean> <tx:annotation-driven /> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> </beans>
and annotated my addUser() method with @Transactional annotation like this:
package umk.dumont.models; ... public class RegisterFormModel implements Serializable { private String login; private String password; private String email; @Autowired private RegisterDAO registerDAO = null; ... @Transactional public boolean addUser() { MyUser user = new MyUser(); user.setLogin(login); user.setPassword(password); user.setEmail(email); return registerDAO.insertUserIntoDB(user) == 0 ? true : false; } ... }
or even annotated whole class by this annotation:
package umk.dumont.models; ... @Transactional public class RegisterFormModel implements Serializable { private String login; private String password; private String email; @Autowired private RegisterDAO registerDAO = null; ... public boolean addUser() { MyUser user = new MyUser(); user.setLogin(login); user.setPassword(password); user.setEmail(email); return registerDAO.insertUserIntoDB(user) == 0 ? true : false; } ... }
but in both cases problem is the same - data doesn't stored in database. Is there any problem with my AOP proxing, because I'm newbie in this (just like in whole Spring :))?
EDIT: In my persistence.xml I am using
transaction-type="JTA
" so I think I should use<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
in my applicationContext.xml - am I right?