2016-04-30 20 views
0

私は3つのクラス(サービス層のUserSrvImpl、DAO(リポジトリ)層のMailDaoImplとUserDaoImpl)を持っています。私のサービスレイヤー(UserSrvImpl)では、私はMailDaoImplのメソッドとUserDaoImplのメソッドを呼び出すメソッドを持っています。これらの2つのDAOメソッドは、2つの異なるテーブルにオブジェクトを保存する必要があります。これらの2つのテーブルには、OneToOneリレーションシップがあります。私の問題は、最初の挿入が成功し、2番目が失敗し、ロールバックが失敗したときです。私は1週間以来この問題に苦しんでいます。私はGoogleで見つけたすべてのソリューションを適用しましたが、まだ成功していません。私に助けてもらえますか?ここ は私のサービス層である:@サービス層上の@ Transactionalはロールバックしません。Spring MVC + Hibernate

@Service 
public class UserSrvImpl implements IUserSrv { 
@Autowired 
private IUserDao userDao; 
@Autowired 
private IMailDao mailDao; 

@Override 
@Transactional 
public boolean create(UserDto userDto) { 
    boolean result = false; 
    try { 
     User userToSave = transformDtoToEntity(userDto); 
     MailToken mailToken = createMailTokenForNewUser(userToSave); 

     userToSave.setMailToken(mailToken); 
     if (mailDao.createMailToken(mailToken)) { 
      result = userDao.create(userToSave); 
     } 

    } catch (Exception ex) { 

    } 
    return result; 
} 

サービスは、DAOのメソッドmailDao.createMailTokenとuserDao.create呼びかけています。最初に成功し、2番目が失敗した場合、データベースの最初のテーブルにロールバックはありません。以下は

@Repository 
public class MailDao implements IMailDao { 
@Autowired 
private SessionFactory sessionFactory; 

public Session getSession() { 
    Session sess = this.sessionFactory.getCurrentSession(); 
    if (sess == null) { 
     sess = this.sessionFactory.openSession(); 
    } 
    return sess; 
} 

@Override 
public boolean createMailToken(MailToken mailToken) { 
    try { 
     getSession().save(mailToken); 
     return true; 
    } catch (HibernateException ex) { 

    } catch (Exception ex) { 
     // TODO: handle exception 
    } 
    return false; 
} 

UserDaoImplでコードされています:

@Repository 
public class UserDaoImpl implements IUserDao { 

@Autowired 
private SessionFactory sessionFactory; 

public Session getSession() { 
    Session sess = this.sessionFactory.getCurrentSession(); 
    if (sess == null) { 
     sess = this.sessionFactory.openSession(); 
    } 
    return sess; 
} 

@Override 
public boolean create(User userToSave) { 
    try { 
     getSession().save(userToSave); 
     return true; 
    } catch (HibernateException ex) { 
     ex.printStackTrace(); 

    } catch (Exception ex) { 
     // TODO: handle exception 
    } 

    return false; 
} 

これは私の春の構成です: 以下MailDaoでコードがあるあなたはなぜ私に言うことができるしてください

<bean id="hibernate5AnnotatedSessionFactory" 
    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"></property> 
    <property name="packagesToScan"> 
     <array value-type="java.lang.String"> 
      <value>com.pointsante.dao.domaine</value> 
     </array> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 
      <prop key="hibernate.hbm2ddl.auto">validate</prop> 
     </props> 
    </property> 
</bean> 
<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"></property> 
</bean> 
<tx:annotation-driven transaction-manager="transactionManager" /> 

は@サービス層のメソッドのトランザクションは機能していません。ありがとうございました。

+0

私はまたすべてのtry catchブロックを削除しようとしましたが、そこにはまだ問題があります – Alee

答えて

0

おそらくDataSourceTransactionManagerの代わりにHibernateTransactionManagerを使用するべきです。

使用

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

代わりの

<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"></property> 
</bean> 

は、サービスが呼び出された場所から確認してください。サービスクラス自体から呼び出すと、トランザクション管理を処理するプロキシは使用されません。

+0

ルーメンありがとうございます。 HibernateTransactionManagerによるDataSourceTransactionManagerの置き換えは、問題を解決しました。 – Alee

+0

次に、あなたの 'getSession'メソッドは危険です。 'getCurrentSession'だけを使用しても、' openSession'は使用されません。これは、springのトランザクション管理の範囲外で新しいセッションを開きます。 –

関連する問題