[英]Why nothing happens when I persist?
我希望我不會問你已經回答的問題,但我無法理解我的問題...我解釋說:
我使用Spring和Hibernate,我有一個Manager接口,以及一個實現我的界面的Manager。 經理是這樣的:
@Service
@Transactional
public class ManagerImpl implements Manager {
@PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName="Service")
private EntityManager em;
public void storeHistoricMessage(...params...) throws DBException{
HistoricMessage historicMessage = new HistoricMessage();
// ... initialization of historicMessage
try {
em.persist(historicMessage);
}
catch (Exception e){
// process the exception if exists...
}
}
}
我這樣稱呼我的服務:
@Service
public class OtherManager {
@Autowired
private Manager manager;
public void storeHistoricMessage(...params...) {
manager.storeHistoricMessage(...params...);
}
}
我的應用程序上下文定義如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:component-scan base-package="package" />
<bean id="JDBCPropertyConfigurer_service"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="JDBCProperties_service" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="JDBCProperties_service"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager_service"/>
<bean id="transactionManager_service" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory_service" />
</bean>
<!-- datasource -->
<bean id="dataSource_service"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database_service.driverClassName}" />
<property name="url" value="${database_service.url}" />
<property name="username" value="${database_service.username}" />
<property name="password" value="${database_service.password}" />
</bean>
<!-- JPA config -->
<bean id="entityManagerFactory_service"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource_service" />
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="Service" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<!--
<property name="generateDdl" value="${jpa.generateDdl}" />
<property name="showSql" value="${jpa.showSql}" /> <property
name="hbm2ddl.auto" value="${jpa.hbm2ddl}" />
-->
</bean>
</property>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
最后,我的persistence.xml是這樣的:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="Service" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>package.HistoricMessage</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.archive.autodetection" value="class, hbm" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.hbm2ddl.auto" value="${hibernate.hbm2ddl.auto}" />
</properties>
</persistence-unit>
</persistence>
問題是,當我堅持,沒有任何反應:沒有插入數據庫,沒有錯誤信息,沒有異常......我做了很多測試,我也許有一些幫助:
最后,這里是我可以看到的TRACE日志:
DEBUG 12-01 10:50:01,362 (SessionImpl.java:<init>:220) -opened session at timestamp: 13263618013
DEBUG 12-01 10:50:01,362 (JDBCTransaction.java:begin:54) -begin
DEBUG 12-01 10:50:01,362 (ConnectionManager.java:openConnection:421) -opening JDBC connection
DEBUG 12-01 10:50:01,363 (DriverManagerDataSource.java:getConnectionFromDriver:163) -Creating new JDBC DriverManager Connection to [jdbc:mysql://databaseurl]
DEBUG 12-01 10:50:01,378 (JDBCTransaction.java:begin:59) -current autocommit status: true
DEBUG 12-01 10:50:01,379 (JDBCTransaction.java:begin:62) -disabling autocommit
TRACE 12-01 10:50:01,380 (JDBCContext.java:afterTransactionBegin:214) -after transaction begin
DEBUG 12-01 10:50:01,380 (JpaTransactionManager.java:doBegin:348) -Exposing JPA transaction as JDBC transaction [SimpleConnectionHandle: com.mysql.jdbc.JDBC4Connection@1ff335bb]
TRACE 12-01 10:50:01,381 (TransactionSynchronizationManager.java:bindResource:186) -Bound value [org.springframework.jdbc.datasource.ConnectionHolder@184c9860] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@65499154] to thread [http-8001-Processor5]
TRACE 12-01 10:50:01,381 (TransactionSynchronizationManager.java:bindResource:186) -Bound value [org.springframework.orm.jpa.EntityManagerHolder@4ca7d316] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@28ce2c57] to thread [http-8001-Processor5]
TRACE 12-01 10:50:01,381 (TransactionSynchronizationManager.java:initSynchronization:261) -Initializing transaction synchronization
TRACE 12-01 10:50:01,382 (TransactionAspectSupport.java:prepareTransactionInfo:290) -Getting transaction for [package.storeHistoricMessage]
storeHistoricMessage (begin of my function)
DEBUG 12-01 10:50:01,382 (EntityManagerFactoryUtils.java:doGetTransactionalEntityManager:194) -Opening JPA EntityManager
DEBUG 12-01 10:50:01,388 (EntityManagerFactoryUtils.java:doGetTransactionalEntityManager:199) -Registering transaction synchronization for JPA EntityManager
DEBUG 12-01 10:50:01,389 (SessionImpl.java:<init>:220) -opened session at timestamp: 13263618013
TRACE 12-01 10:50:01,392 (TransactionSynchronizationManager.java:bindResource:186) -Bound value [org.springframework.orm.jpa.EntityManagerHolder@69851576] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@20442c19] to thread [http-8001-Processor5]
TRACE 12-01 10:50:01,393 (IdentifierValue.java:isUnsaved:77) -id unsaved-value strategy UNDEFINED
TRACE 12-01 10:50:01,394 (AbstractSaveEventListener.java:getEntityState:514) -transient instance of: package.HistoricMessage
TRACE 12-01 10:50:01,394 (DefaultPersistEventListener.java:entityIsTransient:124) -saving transient instance
DEBUG 12-01 10:50:01,397 (AbstractSaveEventListener.java:saveWithGeneratedId:112) -generated identifier: ***identifier***, using strategy: org.hibernate.id.Assigned
TRACE 12-01 10:50:01,397 (AbstractSaveEventListener.java:performSave:153) -saving [package.HistoricMessage#***identifier***]
end of my function
TRACE 12-01 10:50:01,399 (TransactionAspectSupport.java:commitTransactionAfterReturning:319) -Completing transaction for [package.storeHistoricMessage]
TRACE 12-01 10:50:01,400 (AbstractPlatformTransactionManager.java:triggerBeforeCommit:903) -Triggering beforeCommit synchronization
TRACE 12-01 10:50:01,400 (AbstractPlatformTransactionManager.java:triggerBeforeCompletion:916) -Triggering beforeCompletion synchronization
TRACE 12-01 10:50:01,401 (TransactionSynchronizationManager.java:doUnbindResource:232) -Removed value [org.springframework.orm.jpa.EntityManagerHolder@69851576] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@20442c19] from thread [http-8001-Processor5]
DEBUG 12-01 10:50:01,401 (EntityManagerFactoryUtils.java:closeEntityManager:313) -Closing JPA EntityManager
TRACE 12-01 10:50:01,401 (SessionImpl.java:close:273) -closing session
TRACE 12-01 10:50:01,402 (ConnectionManager.java:cleanup:375) -connection already null in cleanup : no action
DEBUG 12-01 10:50:01,402 (AbstractPlatformTransactionManager.java:processCommit:730) -Initiating transaction commit
DEBUG 12-01 10:50:01,402 (JpaTransactionManager.java:doCommit:451) -Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@27b71c12]
DEBUG 12-01 10:50:01,403 (JDBCTransaction.java:commit:103) -commit
TRACE 12-01 10:50:01,403 (SessionImpl.java:managedFlush:337) -automatically flushing session
TRACE 12-01 10:50:01,403 (JDBCContext.java:beforeTransactionCompletion:205) -before transaction completion
TRACE 12-01 10:50:01,404 (SessionImpl.java:beforeTransactionCompletion:393) -before transaction completion
DEBUG 12-01 10:50:01,405 (JDBCTransaction.java:toggleAutoCommit:193) -re-enabling autocommit
DEBUG 12-01 10:50:01,406 (JDBCTransaction.java:commit:116) -committed JDBC Connection
TRACE 12-01 10:50:01,407 (JDBCContext.java:afterTransactionCompletion:219) -after transaction completion
DEBUG 12-01 10:50:01,407 (ConnectionManager.java:aggressiveRelease:404) -aggressively releasing JDBC connection
DEBUG 12-01 10:50:01,408 (ConnectionManager.java:closeConnection:441) -releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
TRACE 12-01 10:50:01,408 (SessionImpl.java:afterTransactionCompletion:422) -after transaction completion
TRACE 12-01 10:50:01,409 (AbstractPlatformTransactionManager.java:triggerAfterCommit:929) -Triggering afterCommit synchronization
TRACE 12-01 10:50:01,409 (AbstractPlatformTransactionManager.java:triggerAfterCompletion:945) -Triggering afterCompletion synchronization
TRACE 12-01 10:50:01,410 (TransactionSynchronizationManager.java:clearSynchronization:315) -Clearing transaction synchronization
TRACE 12-01 10:50:01,410 (TransactionSynchronizationManager.java:doUnbindResource:232) -Removed value [org.springframework.orm.jpa.EntityManagerHolder@4ca7d316] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@28ce2c57] from thread [http-8001-Processor5]
TRACE 12-01 10:50:01,410 (TransactionSynchronizationManager.java:doUnbindResource:232) -Removed value [org.springframework.jdbc.datasource.ConnectionHolder@184c9860] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@65499154] from thread [http-8001-Processor5]
DEBUG 12-01 10:50:01,411 (JpaTransactionManager.java:doCleanupAfterCompletion:534) -Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl@27b71c12] after transaction
DEBUG 12-01 10:50:01,411 (EntityManagerFactoryUtils.java:closeEntityManager:313) -Closing JPA EntityManager
TRACE 12-01 10:50:01,411 (SessionImpl.java:close:273) -closing session
TRACE 12-01 10:50:01,412 (ConnectionManager.java:cleanup:375) -connection already null in cleanup : no action
非常感謝你的幫助!
編輯:我很抱歉,我理解發生了什么,你無法找到,因為我真的簡化了我的項目的架構,我沒有告訴你原因:在這個項目中,我有幾個應用程序上下文文件和幾個數據源,所以我使用了幾次....而對於Spring 2.5,你只能有一個! 所以我不能在我的第二個服務中使用交易...為了解決這個問題,我使用了這樣的aop:
<tx:advice id="txAdviceSelfCare" transaction-manager="transactionManager_service">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="ServiceManagerOperations"
expression="execution(* package.ServiceManager.*(..))" />
<aop:advisor advice-ref="txAdviceService"
pointcut-ref="ServiceManagerOperations" />
</aop:config>
<!-- a PlatformTransactionManager is still required -->
<bean id="transactionManager_service" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory_service" />
</bean>
感謝你的幫助 !
你能嘗試檢查數據庫中真正發生的事情嗎? 嘗試激活該數據庫上的日志工具,如果安裝了這樣的工具來嗅探Java代碼和數據庫服務器之間的網絡流量...它可能很有用......你可以要求你的JPA層顯示生成的SQL,它可以給你有趣的數據...我的2件jerome
更改您的catch塊以執行某些操作並查看其打印內容。
try {
em.persist(historicMessage);
}
catch (Exception e){
e.printStackTrace(); // use a logger if available
}
您還可以將以下屬性更改為true
以查看正在發生的情況。
<property name="hibernate.show_sql" value="true" />
此外,養成使用合適的日志框架(如SLF4J)跟蹤方法進入/退出的習慣。
請注意,實際插入不會發生在em.persist語句中,因為調用是事務性的,所以你的try / catch根本不會做太多。 實際的持久化是在事務結束時完成的,即服務層調用完成時(從方法返回后)。 調試持久性時,這些知識至關重要。
驗證數據庫在哪里查看詳細信息。 日志清楚地表明提交已完成..
DEBUG 12-01 10:50:01,403 (JDBCTransaction.java:commit:103) -commit TRACE 12-01 10:50:01,403 (SessionImpl.java:managedFlush:337) -automatically flushing session TRACE 12-01 10:50:01,403 (JDBCContext.java:beforeTransactionCompletion:205) -before transaction completion TRACE 12-01 10:50:01,404 (SessionImpl.java:beforeTransactionCompletion:393) -before transaction completion DEBUG 12-01 10:50:01,405 (JDBCTransaction.java:toggleAutoCommit:193) -re-enabling autocommit DEBUG 12-01 10:50:01,406 (JDBCTransaction.java:commit:116) -committed JDBC Connection
將您的方法調用放在try catch中
public void storeHistoricMessage(...params...) {
try {
manager.storeHistoricMessage(...params...);
} catch (Exception e) {
e.printStackTrace(); // use a logger if available
}
}
數據應該在manager.storeHistoricMessage方法調用(通過事務管理代理)結束時保留,而不是在em.persist調用。 你也可以試試em.flush:
try {
em.persist(historicMessage);
em.flush(); //force DB insert
}...
看起來你並沒有看到一個異常,因為交易經理可能會拋出這個異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.