2016-05-14 21 views
1

別のDAOネイティブクエリを呼び出した後、トランザクション自動コミットに問題があります。Spring 4 + Hibernate 5.1別のDAOクエリを呼び出した後にトランザクション自動コミット

@Transactionalとして署名されたサービスとDAOの両方。

私はここで間違っていますか?

春4.2.xでは

にHibernate 5.1.0

Atomikos 3.9.3

これは私の設定です:

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="jtaPlatformAdapter" class="com.xxx.JtaPlatformAdapter"> 
    <property name="jtaTransactionManager" ref="transactionManager" /> 
</bean> 

<bean class="com.atomikos.icatch.jta.UserTransactionManager" destroy-method="close" id="atomikosTransactionManager" init-method="init"> 
    <property name="forceShutdown" value="true" /> 
    <property name="startupTransactionService" value="true" /> 
</bean> 

<bean class="com.atomikos.icatch.jta.UserTransactionImp" id="atomikosUserTransaction" /> 

<bean class="org.springframework.transaction.jta.JtaTransactionManager" id="transactionManager"> 
    <property name="transactionManager" ref="atomikosTransactionManager" /> 
    <property name="userTransaction" ref="atomikosUserTransaction" /> 
</bean> 


<bean id="datasouce" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> 
    ... 
</bean> 

<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" id="JPAVendorAdapter"> 
    ... 
</bean> 

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="emf" depends-on="transactionManager,jtaPlatformAdapter"> 
    <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" /> 
    <property name="packagesToScan" value="com.xxx.server"/> 
    <property name="dataSource" ref="datasouce" /> 
    <property name="persistenceUnitName" value="pun" /> 
    <property name="jpaVendorAdapter" ref="JPAVendorAdapter" /> 
    <property name="jpaPropertyMap"> 
     <map> 
      <entry key="hibernate.connection.release_mode" value="on_close" /> 
      <entry key="hibernate.transaction.jta.platform" value="com.xxx.server.JtaPlatformAdapter" /> 
     </map> 
    </property> 
</bean> 

persistence.xmlの

<persistence-unit name="pun" transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 

サービス

@Transactional 
@Scope("prototype") 
public synchronized void save(EntityObj model) throws Exception { 
    model.setX(30); 
    model.setY(40); 

    EntityObj oldModel = entityObjDAO.findById(model.getId()); 
    // after call findById, the model had been commit to DB 
    ... 
    ... 
    ... 

    entityObjDAO.store(model); // this will call entityManager.merge(model) 
    entityObjDAO.flush(); 
} 

DAO

@Transactional 
public EntityObj findById(String id) { 
    EntityObj model = null; 
    String sql = "select id,x,y from EntityObj where id = :id"; // this is a native sql query 

    Query query = this.entityManager.createNativeQuery(sql); 
    query.setParameter("id", id); 
    Object[] rs = (Object[]) query.getSingleResult(); 
    if (rs != null) { 
     model = new EntityObj(); 
     model.setId(id); 
     model.setX(rs[1] == null ? null : (Integer) rs[1]); 
     model.setY(rs[2] == null ? null : (Integer) rs[2]); 
    } 

    return model; 
} 

感謝!

+0

plsもっと多くの情報、より多くのコード:) – dit

+0

@ditサービスのコードとDAOを追加しました。ありがとう。 –

+0

問題は何ですか? – dit

答えて

1

コードで@Transactionalを使用している場合、SpringはDaoオブジェクト(ラッパー)用のプロキシオブジェクトを作成します。アプリケーションが実行されている場合

だから、それは次のようになります。

public EntityObj proxyMethodForFindById(String id) { 

    try { 
     // 1. start transaction 
     startTransaction(); 

     // 2. execute your code 
     return yourDaoObject.findById(id); 

    } finally { // [!] PSEUDO CODE: NO EXCEPTION HANDLING 

     // commit transaction 
     commitTransaction(); 
    } 

} 

だから何があなたのコードになりますか?

保存方法には@Transactionalと表示されます。だから、あなたが設定してオブジェクトを変更する場合:

model.setX(30); 
model.setY(40); 

春の2つのプロキシを作成します。 1つはService、もう1つはDaoです。 findByIdの終了時に、この変更がコミットされます。ネストされたトランザクションがキーワードです。

findByIdの方法でDaoオブジェクト全体で@Transactionを削除する必要があります。 ServiceはDao層ではなくトランザクションである必要があります。

+0

あなたの答えをありがとう! メソッドとクラスから@Transactionalを削除しますが、トランザクションは依然として実行クエリの後にコミットされます。 –

+0

@ T.SETはい、それはあなたが同じ「触れられた」オブジェクトを得ているからです。だから、これをコミットすることはできませんでしたこれはあなたが上記の変更です。 – dit

関連する問題