Не удалось открыть JPA EntityManager для транзакции с использованием MongoDB

Попытка использовать Spring, Hibernate-OGM с MongoDB. Однако возникла проблема с транзакциями. Я знаю, что они не поддерживаются MongoDB, однако я хочу использовать аннотацию @transactional, поэтому мне не нужно начинать, фиксировать.

Исключение

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:430)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:420)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:257)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)

Контекст БД.xml

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="mongo-hibernate"/>    
  </bean>

  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>

  <tx:annotation-driven transaction-manager="transactionManager"/>

постоянство.xml

<persistence-unit name="mongo-hibernate" transaction-type="JTA">
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

        <properties>
           <property name="hibernate.current_session_context_class" value="thread"/>                        
           <property name="hibernate.ogm.datastore.provider" value="mongodb"/>
           <property name="hibernate.ogm.datastore.grid_dialect" value="org.hibernate.ogm.datastore.mongodb.MongoDBDialect"/>           
           <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>                
            <property name="hibernate.ogm.datastore.database" value="mongodbtest"/>
            <property name="hibernate.ogm.mongodb.database" value="mongodbtest"/>
            <property name="hibernate.ogm.mongodb.host" value="localhost"/>
            <property name="hibernate.ogm.mongodb.associations.store" value="IN_ENTITY"/>
        </properties>

    </persistence-unit>
</persistence>

ДАО

@PersistenceContext
protected EntityManager entityManager;

@Transactional(readOnly = false)
public <E> void updateObject(E entity) {
   entityManager.persist(entity);
 }

любая помощь приветствуется. Спасибо


person Dima    schedule 29.08.2014    source источник


Ответы (2)


Пока я продвинулся немного дальше, я изменил некоторые файлы на:

Контекст БД.xml

   <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="mongo-hibernate"/>    
  </bean>

  <bean class="com.arjuna.ats.jta.TransactionManager" factory-method="transactionManager" id="arjunaTransactionManager"/>
  <bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction" id="arjunaUserTransaction"/>  

  <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="arjunaTransactionManager"/>
    <property name="userTransaction" ref="arjunaUserTransaction"/>
  </bean>

  <tx:annotation-driven transaction-manager="transactionManager"/>

ДАО:

@PersistenceContext
protected EntityManager entityManager;

@Transactional(readOnly = false)
public <E> void updateObject(E entity) {

    Session session = entityManager.unwrap(Session.class);          
    org.hibernate.Transaction tx = session.getTransaction();  
    tx.begin();
    session.persist(entity);
    tx.commit();

}

Таким образом, все работает нормально, однако мне бы очень хотелось, чтобы он работал проще, например:

@Transactional(readOnly = false)
public <E> void updateObject(E entity) {
   entityManager.persist(entity);
 }

Какие-либо предложения?

person Dima    schedule 29.08.2014
comment
Извините за некро, а вы разобрались? Я изо всех сил пытаюсь заставить его работать с последним Hibernate OGM. Спасибо - person Dan; 25.08.2016
comment
В принципе нечего выяснять. MongoDB не поддерживает транзакции. Вы можете сделать так же, как упоминалось, ради стандарта я использую все, что делаю при разработке для транзакций. Однако недавно я переключился на проект SPRING для mongodb, пока он мне очень нравится. - person Dima; 26.08.2016
comment
Ну, на самом деле я понял это вскоре после того, как спросил. Единственное, что было не так, это то, что я не использовал @Transactional в управляемом bean-компоненте Spring. И да, сама MongoDB не поддерживает транзакции, но все же предлагает разграничить операцию (ссылка). - person Dan; 26.08.2016

Да, у меня есть предложение: прочитайте документы. ;)

"MongoDB не поддерживает транзакции."

person Markus W Mahlberg    schedule 30.08.2014
comment
Я читал документы, я знаю, что транзакции не поддерживаются, однако ребята из спящего режима по-прежнему советуют использовать стандартный синтаксис @Transactional. - person Dima; 31.08.2014
comment
Вот примечание от hibernate, предлагающее использовать @transactional, даже если они не поддерживаются docs.jboss.org/hibernate/ogm/4.0/reference/en-US/html_single/ - person Dima; 01.09.2014