を更新2011年12月12日春にHibernateのトランザクションの例外のロールバック
アプリケーションがhere見つけることができるジェネリックDAOクラスを利用しています。
@Repositoryの使用方法についてspring manualを再読したところ、例外翻訳を処理するためにGenericDAOの実装にこれを追加する必要があるようです。
@RepositoryをGenericDAOに追加しましたが、結果は変更されませんでした。親オブジェクトはまだデータベースに保持されています。
私は私の取引は例外が発生した場合に正しくロールバックされますことを確認するためにいくつかのテストをやって春2.5.6、その休止バージョン、春のMVCでのJBoss 5.1、MySQLのを使用して
。以下のコードでは、2番目のメソッド:createProfileはメソッドの完了を妨げるNullPointerExceptionをスローします。私はその取引がロールバックされることを期待していました。私が探しているのは、ユーザーオブジェクトがデータベースに保持されているということです。私が望むのは、2番目の操作が失敗した場合、最初の操作もロールバックする必要があるということです。
私は親メソッドのREQUIRED_NEWへの伝播を変更したが、動作に変更は見られなかったいくつかの変更を行いました。
私は春の取引のログを有効にしました。
私は別の投稿を見直して、what spring has to say on transactions as wellを確認しています。私はトランザクションの行為に沿って何かが欠けているようです。
私はここで間違っています。
私は次のように定義さ
@Transactional(propagation = Propagation.SUPPORTS)
public class ProfileServiceImpl implements ProfileService
{
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public boolean createProfile(UserDTO pUserDTO, ContactInfoDTO pContactInfoDTO)
{
boolean retVal = false;
if(this.createProfile(pUserDTO))
{
if(this.addAddressToUser(pContactInfoDTO, pUserDTO.getId()))
{
retVal = true;
}
}
return retVal;
}
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public boolean createProfile(UserDTO userDTO)
{
boolean retVal = false;
if(this.getProfileQueries().isLoginUnique(userDTO.getLogin(),userDTO.getSiteInfoId()))
{
User user = new User();
BeanUtils.copyProperties(userDTO, user);
user.setPassword(this.stringDigester.digest(userDTO.getPassword()));
user.setSiteInfo(this.getSiteInfoDao().read(userDTO.getSiteInfoId()));
user.setSecurityLevel(SecurityLevel.ROLE_USER);
user.setStatus(Status.ACTIVE);
Long pk = this.getUserDao().create(user);
userDTO.setId(pk);
retVal = true;
}
return retVal;
}
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
public boolean addAddressToUser(ContactInfoDTO pAddress, Long pProfileId)
{
boolean retVal = false;
if(null != pAddress && null != pProfileId)
{
ContactInfo contactInfo = new ContactInfo();
BeanUtils.copyProperties(pAddress, contactInfo);
User user = this.getUserDao().read(pProfileId);
contactInfo.setUser(user);
this.getContactInfoDao().create(contactInfo);
user.getUserAddress().setProfileAddress(contactInfo);
user.getUserAddress().setBillingAddress(contactInfo);
this.getUserDao().update(user);
retVal = true;
}
return retVal;
}
}
データ設定
<!-- TRANSACTION MANAGER-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- ANNOTATION DRIVEN TRANSACTIONS -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/MySqlDS"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="jndiDataSource"/>
<property name="annotatedClasses">
<list>
<value>com.vsg.dataaccess.user.entity.User</value>
<value>com.vsg.dataaccess.user.entity.ContactInfo</value>
<value>com.vsg.dataaccess.user.entity.UserAddress</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>
<prop key="hibernate.jdbc.batch_size">20</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</prop>
<prop key="net.sf.ehcache.configurationResourceName">ehcache.xml</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="org.hibernate.envers.audit_table_suffix">_aud</prop>
<prop key="org.hibernate.envers.revision_field_name">rev_number</prop>
<prop key="org.hibernate.envers.revision_type_field_name">rev_type</prop>
<prop key="org.hibernate.envers.revision_on_collection_change">true</prop>
</props>
</property>
<property name="entityInterceptor">
<bean class="vsg.ecotrak.dataaccess.framework.hibernate.interceptor.AuditTrailInterceptor"/>
</property>
</bean>
実際にメソッドをどのように呼び出すかを確認する必要があります。実際にプロキシの境界を越える前に、サービスが自己呼び出しして例外をキャッチしていると推測できます。 (コンテキストがちょうど間違って設定されていて、トランザクションマネージャがentitymanagerファクトリに接続されていないので、自動コミットモードでユーザを作成しています) – Affe
コントローラクラスからメソッドが呼び出されています – boyd4715
UserDao - 休止状態のセッションをどのように管理していますか。あなたはhibernateTemplateを使用していますか? – gkamal