entityManager.persist() 的经典问题:没有错误但没有插入到数据库
The Classic issue of entityManager.persist(): no errors but not inserting to db
我在插入新条目时遇到了一个奇怪的问题。
问题:
entityManager.persist(myEntiy)
: 行被执行但没有在数据库中创建条目。
我知道很多人以前遇到过这个问题,我已经阅读了所有这些帖子,但是 none 其中的内容回答了我的问题。我不是第一次插入条目。所以我已经正确地完成了配置和其他基本的事情。这意味着我确实在我的 spring-core.xml 中使用了 <tx:annotation-driven transaction-manager="jpaTransactionManager"/>
并且我确实在我的 dao 中的方法之上使用了 @Transactional
。
尝试过的解决方案: 在坚持后添加 entityManager.flush()
,但这导致了
javax.persistence.TransactionRequiredException: no transaction is in
progress.
也试过:
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
这导致
Not allowed to create transaction on shared EntityManager
然后看到有人说问题可能是的
AbstractSaveEventListener - delaying identity-insert due to no
transaction in progress
但我在日志中没有任何内容表明这可能是原因。如果那是问题所在,我不知道解决方案到底是什么。我的休眠日志以这些行结尾。
DEBUG 0412185908 [80-exec-2 SqlStatementLogger.java: 104] select mySchema.sequence_for_my_entity_PK.nextval from dual
DEBUG 0412185908 [80-exec-2 SequenceGenerator.java: 127] Sequence identifier generated: BasicHolder[java.lang.Long[20]]
DEBUG 0412185908 [80-exec-2 AbstractSaveEventListener.java: 131] Generated identifier: 20, using strategy: org.hibernate.id.SequenceHiLoGenerator
DEBUG 0412185908 [80-exec-2 LogicalConnectionImpl.java: 314] Releasing JDBC connection
DEBUG 0412185909 [80-exec-2 LogicalConnectionImpl.java: 332] Released JDBC connection
DEBUG 0412185909 [80-exec-2 ConnectionProxyHandler.java: 219] HHH000163: Logical connection releasing its physical connection
那里没有任何错误。感谢您的帮助。
我的spring-core.xml有:
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref= "jpaVendorAdapter"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="punit" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<tx:annotation-driven transaction-manager="jpaTransactionManager"/>
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${local.datasource.database.platform}" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
<bean id="dataSource" class="${local.datasource.database.datasource}">
<property name="dataSourceName" value="${local.datasource.database.name}" />
<property name="URL" value="${local.datasource.database.url}" />
<property name="user" value="${local.datasource.database.user}" />
<property name="password" value="${local.datasource.database.password}" />
</bean>
而 DaoImpl 是:
@Repository
public class MyDaoImpl implements MyDao {
protected EntityManager entityManager;
@Autowired
AnotherDao anotherDao;
public EntityManager getEntityManager() {
return entityManager;
}
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
@Transactional
public String saveNewInfo(Data dataObject, String scheduleType){
String uniqueSessionId = null;
History history = new History();
SessionIdentifierGenerator sessionIdentifierGenerator = new SessionIdentifierGenerator();
uniqueSessionId = sessionIdentifierGenerator.nextSessionId();
Type type = anotherDao
.getAppObject(dataObject.getApplication());
history.setType(type.getType());
history.setSessionId(uniqueSessionId);
history.setSchedulerType(scheduleType);
history.setStatusCode("1");
history.setVersionNumber(dataObject.getVersionNumber());
entityManager.persist(history);
return uniqueSessionId;
}
}
这样问题就解决了。我将这两行添加到我的 Spring-Core.xml
<bean id="myDao" class="com.myPackage.dao.myDaoImpl"/>
<bean id="myAnotherDao" class="com.myPackage.dao.myAnotherDaoImpl" />
我以前在 spring-core 中从未使用过像这样的 dao bean 指定,但它仍然用于更新、删除甚至持久化新条目(欢迎大家澄清这部分)。但这是解决我的问题的解决方案。
我在插入新条目时遇到了一个奇怪的问题。
问题:
entityManager.persist(myEntiy)
: 行被执行但没有在数据库中创建条目。
我知道很多人以前遇到过这个问题,我已经阅读了所有这些帖子,但是 none 其中的内容回答了我的问题。我不是第一次插入条目。所以我已经正确地完成了配置和其他基本的事情。这意味着我确实在我的 spring-core.xml 中使用了 <tx:annotation-driven transaction-manager="jpaTransactionManager"/>
并且我确实在我的 dao 中的方法之上使用了 @Transactional
。
尝试过的解决方案: 在坚持后添加 entityManager.flush()
,但这导致了
javax.persistence.TransactionRequiredException: no transaction is in progress.
也试过:
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
这导致
Not allowed to create transaction on shared EntityManager
然后看到有人说问题可能是的
AbstractSaveEventListener - delaying identity-insert due to no transaction in progress
但我在日志中没有任何内容表明这可能是原因。如果那是问题所在,我不知道解决方案到底是什么。我的休眠日志以这些行结尾。
DEBUG 0412185908 [80-exec-2 SqlStatementLogger.java: 104] select mySchema.sequence_for_my_entity_PK.nextval from dual
DEBUG 0412185908 [80-exec-2 SequenceGenerator.java: 127] Sequence identifier generated: BasicHolder[java.lang.Long[20]]
DEBUG 0412185908 [80-exec-2 AbstractSaveEventListener.java: 131] Generated identifier: 20, using strategy: org.hibernate.id.SequenceHiLoGenerator
DEBUG 0412185908 [80-exec-2 LogicalConnectionImpl.java: 314] Releasing JDBC connection
DEBUG 0412185909 [80-exec-2 LogicalConnectionImpl.java: 332] Released JDBC connection
DEBUG 0412185909 [80-exec-2 ConnectionProxyHandler.java: 219] HHH000163: Logical connection releasing its physical connection
那里没有任何错误。感谢您的帮助。
我的spring-core.xml有:
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter" ref= "jpaVendorAdapter"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="punit" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<tx:annotation-driven transaction-manager="jpaTransactionManager"/>
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
</bean>
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${local.datasource.database.platform}" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
<bean id="dataSource" class="${local.datasource.database.datasource}">
<property name="dataSourceName" value="${local.datasource.database.name}" />
<property name="URL" value="${local.datasource.database.url}" />
<property name="user" value="${local.datasource.database.user}" />
<property name="password" value="${local.datasource.database.password}" />
</bean>
而 DaoImpl 是:
@Repository
public class MyDaoImpl implements MyDao {
protected EntityManager entityManager;
@Autowired
AnotherDao anotherDao;
public EntityManager getEntityManager() {
return entityManager;
}
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
@Transactional
public String saveNewInfo(Data dataObject, String scheduleType){
String uniqueSessionId = null;
History history = new History();
SessionIdentifierGenerator sessionIdentifierGenerator = new SessionIdentifierGenerator();
uniqueSessionId = sessionIdentifierGenerator.nextSessionId();
Type type = anotherDao
.getAppObject(dataObject.getApplication());
history.setType(type.getType());
history.setSessionId(uniqueSessionId);
history.setSchedulerType(scheduleType);
history.setStatusCode("1");
history.setVersionNumber(dataObject.getVersionNumber());
entityManager.persist(history);
return uniqueSessionId;
}
}
这样问题就解决了。我将这两行添加到我的 Spring-Core.xml
<bean id="myDao" class="com.myPackage.dao.myDaoImpl"/>
<bean id="myAnotherDao" class="com.myPackage.dao.myAnotherDaoImpl" />
我以前在 spring-core 中从未使用过像这样的 dao bean 指定,但它仍然用于更新、删除甚至持久化新条目(欢迎大家澄清这部分)。但这是解决我的问题的解决方案。