Spring事务上下文不会持久化数据

时间:2011-03-10 20:53:09

标签: spring jpa applicationcontext transactional persist

我知道我的问题是一个常见的问题,但我在这里检查了很多问题,检查了Spring文档,我真的不知道我做错了什么。 我的问题:我有一个使用JPA的Spring WebFlow项目(实现:OpenJPA + MySQL数据库)。我使用Spring ORM将EntityManager(通过@PersistenceContext注释)注入到我的简单RegisterDAO中。我已经配置了GlassFishs(我正在使用)连接池以使用MySQL并且一切正常 - 我可以使用我的数据库,但是当我持久化时 - 没有任何反应(数据不会持久存储到数据库)。我知道问题在于我使用的事务上下文。我阅读了Spring Transaction Management的文档,并按照本文档中的配置步骤进行操作。这是我的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>

正如您所看到的,我将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注释。我像这样配置了spring 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>

并使用@Transactional注释注释我的addUser()方法,如下所示:

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" /> - 我是对的吗?

3 个答案:

答案 0 :(得分:1)

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

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

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

我不得不说你在这里有一个非常复杂的设置 - 你可能需要一些试验&amp;缩小范围的错误。将JTA添加到组合中可能没有用 - 你可以尝试使用Spring中的'resource local',直到你开始工作。日志中是否有错误?

答案 1 :(得分:1)

使用

解决了我的问题
import java.util.regex.Matcher;
import java.util.regex.Pattern;

node{    
    stage("parse"){
        def file = readFile 'build.log'

        def regex = ~"(?s)(firstStringToUse(.*)secondStringToUse)"
        Matcher match = regex.matcher(file)
        match.find() {
            capturedText = match.group(1)
            error(capturedText)
        }
    }
}

所以你的bean应该是

org.springframework.orm.jpa.JpaTransactionManager

希望这项工作!

答案 2 :(得分:0)

也许这会有所帮助:

  

在JNDI情况下,在此后处理器的“persistenceUnits”映射中指定相应的JNDI名称,通常在Java EE部署描述符中使用匹配的persistence-unit-ref条目。默认情况下,这些名称被视为资源引用(根据Java EE资源-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