2011-03-10 50 views
4

我知道我的问题是一个常见问题,但我在这里检查了很多问题,检查了Spring文档,我真的不知道我在做什么错误。 我的问题:我有一个使用JPA的Spring WebFlow项目(实现:OpenJPA + MySQL数据库)。我使用Spring ORM向我简单的RegisterDAO注入EntityManager(通过@PersistenceContext注释)。我配置了GlassFishs(我正在使用)使用MySQL的连接池,一切正常 - 我可以使用我的数据库,但是当我坚持一些东西 - 没有任何反应(数据不会持续到数据库)。我知道问题出在我使用的事务上下文上。我阅读了Spring Transaction Management的文档,并按照本文档中的配置步骤进行操作。这是我的applicationContext.xml:Spring事务上下文不会持久数据

<?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> 

正如你可以看到我注射RegisterDAO到我RegisterFormModel,其中包含用于验证登记表数据,并最终将用户添加到数据库,我的业务逻辑。验证工作正常,当我尝试添加新用户时会出现问题。下面是代码:

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; 
     } 
    } 
... 
} 

我也曾尝试使用@Transactional注解。我配置的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:annotation-driven /> 
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> 


</beans> 

并注明我ADDUSER()方法@Transactional注释是这样的:

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; 
    } 

... 
} 

甚至通过这个注解全班同学:

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; 
    } 

... 
} 

但在两种情况下问题都是一样的 - 数据不存储在数据库中。我的AOP接口有问题,因为我是新手(就像整个Spring :))?

编辑:在我的persistence.xml我使用transaction-type="JTA“,所以我觉得我应该在我的applicationContext.xml使用<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> - 我说的对

+0

是的 - 这看起来像JTA的正确的bean定义。 – 2011-03-11 07:16:19

回答

0

也许这将帮助:

在? JNDI的情况下,在后处理器的“persistenceUnits”映射中指定相应的JNDI名称,通常在Java EE部署描述符中使用匹配的persistence-unit-ref条目。默认情况下,这些名称被视为资源引用(根据Java EE resource-ref约定),位于“java:comp/env /”命名空间下方。例如:

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"> 
    <property name="persistenceUnits"> 
     <map> 
      <entry key="unit1" value="persistence/unit1"/> 
      <entry key="unit2" value="persistence/unit2"/> 
     </map> 
    </property> 
</bean> 

来源:

http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.html

+0

感谢您的回复。我认为这个问题并不存在,因为JNDI在我的项目中工作正常 - 持久性单元的名称被正确解析并且EntityManager被正确注入。不过谢谢你的帮助。 – 2011-03-10 23:21:38

+0

顺便说一下 - 我已经检查了这个额外的配置 - 同样的问题:( – 2011-03-10 23:33:26

1

在使用JPA实体管理器代码的版本。尝试在em.persist()之后添加em.flush() - 所有em.persist()所做的都是将该实体附加到持久性上下文。 该实体在那时不是“坚持”的。

你不应该需要em.flush() - 但试试看看它是否有帮助。

当事务结束时,持久化上下文应该自动刷新(写入数据库)。

我不得不说你在这里有一个相当复杂的设置 - 你可能需要一些尝试&错误来缩小它。将JTA添加到组合中可能没有什么帮助 - 您可以在Spring中尝试使用“resource local”,直到您获得它的工作。日志中是否有错误?

+0

我意识到为了在事务性上下文中将数据保存到我的数据库中,JPA需要提交或刷新。但重点是,我无法明确使用em.flush()或em.getTransaction()。commit()/ rollback()/ begin()是因为我正在使用的JTA应该处理这个问题。当我尝试从上面的方法调用一个时,异常是我认为,我只能通过Spring Transaction Management来操作事务日志看起来很好 - 没有错误(在下面发布) – 2011-03-10 23:29:04

+0

信息:使用JTA UserTransaction:com.sun .enterprise.transaction.UserTransactionImpl @ 13536a8 信息:使用JTA TransactionManager:[email protected] 信息:使用JTA TransactionSynchronizationRegistry:com.s u[email protected]1744bd3感谢您的回复。 – 2011-03-10 23:29:29

+0

@ArekWoźniak我明白,最终的解决方案不应该直接包含em.flush。但是你似乎尝试了很多不同的选择,所以建议是细化一个更简单的测试用例。例如。 Junit测试 - 可能在内存数据库中使用 - 只是存储记录。标记为@Transactional的Junit测试将在春季回退。一旦你有简单的配置工作 - 添加额外的组件?也可以打开一些调试日志记录? – 2011-03-11 07:15:12

0

使用

org.springframework.orm.jpa.JpaTransactionManager 

解决了我的问题,所以你的bean应该是

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" /> 

希望这项工作!