Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 切换到JPA,现在我总是在任何插入上获得TransactionRequiredException_Java_Spring_Hibernate_Jpa_Transactions - Fatal编程技术网

Java 切换到JPA,现在我总是在任何插入上获得TransactionRequiredException

Java 切换到JPA,现在我总是在任何插入上获得TransactionRequiredException,java,spring,hibernate,jpa,transactions,Java,Spring,Hibernate,Jpa,Transactions,我有一个Spring4Web应用程序。最初我使用HibernateSessionFactory,并使用Spring Hibernate API进行开发。一切都很顺利。也许我最近愚蠢地决定改用JPA,而Hibernate仍然是我的提供者。我重新配置了Spring设置并重写了大部分代码。最初,测试了一个数据库,以便我所有的数据库读取都能正常工作。然后我尝试了数据库写入,但都失败了,就像这样: javax.persistence.TransactionRequiredException: no tra

我有一个Spring4Web应用程序。最初我使用Hibernate
SessionFactory
,并使用Spring Hibernate API进行开发。一切都很顺利。也许我最近愚蠢地决定改用JPA,而Hibernate仍然是我的提供者。我重新配置了Spring设置并重写了大部分代码。最初,测试了一个数据库,以便我所有的数据库读取都能正常工作。然后我尝试了数据库写入,但都失败了,就像这样:

javax.persistence.TransactionRequiredException: no transaction is in progress
    at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:970)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:342)
    at com.sun.proxy.$Proxy47.flush(Unknown Source)
    at com.taubler.oversite.dao.impl.EntityDaoImpl.insert(EntityDaoImpl.java:65)
    ...
请记住,当使用
HibernateTemplate
SessionFactory
HibernateTransactionManager
等时,我的代码工作得很好。我的业务逻辑类以及DAO都像以前一样使用
@Transactional
进行了注释

Hibernate似乎正在尝试创建事务,正如我在堆栈跟踪之前的日志中看到的:

2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - initial autocommit status: true
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - disabling autocommit
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.internal.SessionImpl - Opened session at timestamp: 14115372286
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - Setting flush mode to: AUTO
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - Setting cache mode to: NORMAL
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.event.internal.AbstractSaveEventListener - Transient instance of: com.taubler.oversite.entities.EmailAddress
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.event.internal.DefaultPersistEventListener - Saving transient instance
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.event.internal.AbstractSaveEventListener - Saving [com.taubler.oversite.entities.EmailAddress#<null>]
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.engine.spi.IdentifierValue - ID unsaved-value: null
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.event.internal.AbstractSaveEventListener - Delaying identity-insert due to no transaction in progress
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.internal.SessionImpl - Opened session at timestamp: 14115372287
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - Setting flush mode to: AUTO
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - Setting cache mode to: NORMAL
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl - rolling back
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - rolled JDBC Connection
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - re-enabling autocommit
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl - after transaction completion
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - after transaction completion
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.internal.SessionImpl - Closing session
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Closing logical connection
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl - Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl@2c4e3947]
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Releasing JDBC connection
2014-09-24 05:40:28 [http-bio-8080-exec-3] DEBUG org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Released JDBC connection
2014-09-24 05:40:28 [http-bio-8080-exec-3] TRACE org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Logical connection closed
那个经理叫道:

...

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

protected final EntityManager getEntityManager() {
    return entityManagerFactory.createEntityManager();
}

public boolean insert(Entity o) {
    o.setCreated(new Date());
    this.getEntityManager().persist(o);
    this.getEntityManager().flush();
    return true;
}
我试过不同的版本。最初,DAO和Manager方法都用
@Transactional(propagation=REQUIRED)注释这就是纯Hibernate的工作方式。我已经尝试删除传播设置,只注释管理器方法,只注释DAO方法。。。什么都不管用

有什么想法吗?
HibernateTransactionManager
JpaTransactionManager
之间似乎有着本质的不同

@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

protected final EntityManager getEntityManager() {
    return entityManagerFactory.createEntityManager();
}
问题是您自己正在创建实体管理器,不要。只需插入
EntityManager
而不是
EntityManager工厂
,并用
@PersistenceContext
而不是
@PersistenceUnit
进行注释。Spring将负责将其绑定到当前事务

@PersistenceContext
private EntityManager entityManager;

protected final EntityManager getEntityManager() {
    return entityManger;
}
如果确实希望继续注入
EntityManager工厂
,请使用
EntityManager工厂utils
getTransactionalEntityManager
方法来获取Spring managed
EntityManager
实例

protected final EntityManager getEntityManager() {
     return EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);
}
另外,它与“普通”hibernate一起工作并不意味着你的设置必须正确。您提到您使用了
HibernateTemplate
,它基本上可以在没有正确事务设置的情况下工作,因为它只会为手头的操作启动一个新的事务。因此,很可能是应用程序在实际无法正常工作的地方似乎正常工作。可能您有多个事务(来自服务层)

另一个注意事项是,您的代码可能很危险

public boolean insert(Entity o) {
    o.setCreated(new Date());
    this.getEntityManager().persist(o);
    this.getEntityManager().flush();
    return true;
}
在您的情况下,这可能会导致创建两个不同的
EntityManager
s,因此您可能在持久化时刷新了另一个。接下来,您不应该调用
flush
,因为这将在事务结束时完成

问题是您自己正在创建实体管理器,不要。只需插入
EntityManager
而不是
EntityManager工厂
,并用
@PersistenceContext
而不是
@PersistenceUnit
进行注释。Spring将负责将其绑定到当前事务

@PersistenceContext
private EntityManager entityManager;

protected final EntityManager getEntityManager() {
    return entityManger;
}
如果确实希望继续注入
EntityManager工厂
,请使用
EntityManager工厂utils
getTransactionalEntityManager
方法来获取Spring managed
EntityManager
实例

protected final EntityManager getEntityManager() {
     return EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);
}
另外,它与“普通”hibernate一起工作并不意味着你的设置必须正确。您提到您使用了
HibernateTemplate
,它基本上可以在没有正确事务设置的情况下工作,因为它只会为手头的操作启动一个新的事务。因此,很可能是应用程序在实际无法正常工作的地方似乎正常工作。可能您有多个事务(来自服务层)

另一个注意事项是,您的代码可能很危险

public boolean insert(Entity o) {
    o.setCreated(new Date());
    this.getEntityManager().persist(o);
    this.getEntityManager().flush();
    return true;
}

在您的情况下,这可能会导致创建两个不同的
EntityManager
s,因此您可能在持久化时刷新了另一个。其次,您不应该调用
flush
,因为这将在事务结束时完成。

您需要使用
@PersistenceContext
注释直接注入
EntityManager
,您需要用
@PersistenceContext
注释直接插入
EntityManager
而不是
PersistenceUnit

,而不是
PersistenceUnit

;谢谢我没有意识到我每次都在创建一个新的EntityManager,但现在这是非常有意义的。另外,HibernateTemplate工作并不是“正确”设置的证明。尽管嵌套的事务性方法应该非常好,尤其是在propagation=REQUIRED的情况下,并且只会产生一个事务。我确实读过,Spring事务传播与JPA事务管理器的行为不同;谢谢我没有意识到我每次都在创建一个新的EntityManager,但现在这是非常有意义的。另外,HibernateTemplate工作并不是“正确”设置的证明。尽管嵌套的事务性方法应该非常好,尤其是在propagation=REQUIRED的情况下,并且只会产生一个事务。我确实读过,Spring事务传播与JPA事务管理器的行为不同。