実行中のトランザクションでpersistを呼び出すと、マップされたオブジェクトがDB(Postgresql 8.4)に永続化されません。SpringTransactionManagementを使用しています
org.springframework.jdbc.datasource.DataSourceTransactionManager
だからすべてがうまくいくはずです。DataSourceのautocommit-modeを「false」に設定しました。モードを「true」に設定すると、コミットが実行されます(そして、オブジェクトは永続化されます)が、それはより大きな問題につながります(たとえば、dbからblobをフェッチする)。したがって、autocommit-modeを「false」に設定する必要があります。これは、誰もが私に言った優先モードでもあります...
これは私の永続性の構成です(コードを必要なものに減らしました):
<bean id="authDatabase" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql://localhost:5432/authentication_db" />
<property name="username" value="test"/>
<property name="password" value="test"/>
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="serviceInfoSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="authDatabase" />
<!-- Very important for transactional usage with org.springframework.jdbc.datasource.DataSourceTransactionManager -->
<property name="useTransactionAwareDataSource" value="true"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<!-- mapped objects, not necessary --->
</list>
</property>
</bean>
<!-- defaults to transactionManager -->
<tx:annotation-driven/>
<bean id="authTXManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="authDatabase"/>
<qualifier value="auth"/>
</bean>
<!-- more stuff -->
また、3つの異なるトランザクションマネージャー(もちろん3つの異なるデータソース)を使用していることにも言及する必要があります...
上記の修飾子属性に反映される私自身のトランザクションアノテーション:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("auth")
public @interface AuthenticationTX{}
オブジェクトを永続化する「必要がある」注釈付きサービスクラス...
@AuthenticationTX
@Override
public void loginClient(Client cl) {
// do stuff
// call dao.persist(cl);
}
これは、db呼び出しを呼び出すサービスメソッドを呼び出すときのログです。
16:21:24,031 DEBUG DataSourceTransactionManager:365 - Creating new transaction with name [com.example.ILoginManager.loginClient]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
16:21:24,078 DEBUG DataSourceTransactionManager:205 - Acquired Connection [jdbc:postgresql://localhost:5432/authentication_db, UserName=auth_user, PostgreSQL Native Driver] for JDBC transaction
Hibernate: select user0_.id as id14_, user0_.email as email14_, user0_.firstname as firstname14_, user0_.isLocked as isLocked14_, user0_.lastLogin as lastLogin14_, user0_.lastname as lastname14_, user0_.loginname as loginname14_, user0_.organisation_id as organis10_14_, user0_.passwort as passwort14_, user0_.userGUID as userGUID14_ from UserAccount user0_ where user0_.loginname=?
Hibernate: select client0_.id as id3_, client0_.clientId as clientId3_, client0_.clientType as clientType3_, client0_.connectedAt as connecte4_3_, client0_.language as language3_, client0_.screenHeight as screenHe6_3_, client0_.screenWidth as screenWi7_3_, client0_.securityToken as security8_3_, client0_.user_id as user9_3_ from Client client0_ where client0_.user_id=?
Hibernate: select user0_.id as id14_, user0_.email as email14_, user0_.firstname as firstname14_, user0_.isLocked as isLocked14_, user0_.lastLogin as lastLogin14_, user0_.lastname as lastname14_, user0_.loginname as loginname14_, user0_.organisation_id as organis10_14_, user0_.passwort as passwort14_, user0_.userGUID as userGUID14_ from UserAccount user0_ where user0_.loginname=?
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into Client (clientId, clientType, connectedAt, language, screenHeight, screenWidth, securityToken, user_id, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update UserAccount set email=?, firstname=?, isLocked=?, lastLogin=?, lastname=?, loginname=?, organisation_id=?, passwort=?, userGUID=? where id=?
16:21:24,187 DEBUG DataSourceTransactionManager:752 - Initiating transaction commit
16:21:24,187 DEBUG DataSourceTransactionManager:265 - Committing JDBC transaction on Connection [jdbc:postgresql://localhost:5432/authentication_db, UserName=auth_user, PostgreSQL Native Driver]
16:21:24,187 DEBUG DataSourceTransactionManager:323 - Releasing JDBC Connection [jdbc:postgresql://localhost:5432/authentication_db, UserName=auth_user, PostgreSQL Native Driver] after transaction
ご覧のとおり、トランザクションは(ログに従って)コミットされていますが、オブジェクトはdbに永続化されていません(挿入と更新は実行されていますが)。
データソース構成でコミットモードをに設定する場合
プロパティname="defaultAutoCommit" value = "true"
すべてが正常に動作します!
何がこの奇妙な問題を引き起こしているのか本当にわかりません...誰かが私にヒントをくれたら嬉しいです。