Транзакционный контекст Spring не сохраняет данные - PullRequest
4 голосов
/ 10 марта 2011

Я знаю, что моя проблема - распространенная проблема, но я проверил много вопросов здесь, проверил документацию Spring и действительно не знаю, что я делаю неправильно. Моя проблема: у меня есть проект Spring WebFlow с использованием JPA (реализация: OpenJPA + база данных MySQL). Я использую Spring ORM для добавления EntityManager (посредством аннотации @PersistenceContext) в мой простой RegisterDAO. Я настроил пулы соединений GlassFishs (которые я использую) для использования MySQL, и все работает - я могу работать с моей базой данных, но когда я что-то сохраняю - ничего не происходит (данные не сохраняются в базе данных). Я знаю, что проблема с транзакционным контекстом, который я использую. Я прочитал документацию Spring Transaction Management и следую инструкциям по настройке в этой документации. Это мое приложениеContext.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. Я настроил весенний 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 ", поэтому я думаю, что я должен использовать <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> в моем applicationContext.xml - я прав?

Ответы [ 3 ]

1 голос
/ 11 марта 2011

В версии кода, в которой используется менеджер сущностей JPA. Попробуйте добавить em.flush () после em.persist () - все, что делает em.persist () - присоединяет сущность к контексту постоянства. В этот момент сущность не «сохраняется».

Вам не нужен em.flush (), но попробуйте, поможет ли он.

Когда транзакция заканчивается, контекст постоянства должен автоматически сбрасываться (записываться в БД).

Я должен сказать, что у вас довольно сложная настройка - вам может понадобиться несколько проб и ошибок, чтобы сузить ее. Добавление JTA в микс может не помочь - вы можете попробовать ресурсные ресурсы в Spring, пока не заработаете. Есть ли ошибки в логах?

1 голос
/ 05 января 2018

решил мою проблему, используя

org.springframework.orm.jpa.JpaTransactionManager

, поэтому ваш бин должен быть

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

надеюсь, что эта работа!

0 голосов
/ 11 марта 2011

Может быть, это поможет:

В случае JNDI укажите соответствующие имена JNDI в карте «persistenceUnits» этого постпроцессора, обычно с соответствующими записями persistence-unit-ref в дескрипторе развертывания Java EE. По умолчанию эти имена рассматриваются как ссылки на ресурсы (в соответствии с соглашением 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...