2011-07-21 2 views
24

私は単一のデータソースを持っていますが、私はSpring 3.0.3、JPAプロバイダとしてHibernate 3.5.1を使用しています。いくつかのクエリでは2つ、Tomcat 6では私のアプリケーションは動いています。HibernateDAOとMyBatisDAOを持っています。@Transactionalで注釈付けされた同じメソッドから両方を呼び出すと、同じトランザクションを共有していないようです。
どうすればいいですか?JPA(Hibernate)とJDBC(JdbcTemplateまたはMyBatis)が同じトランザクションを共有するようにSpringを構成する方法

DataSourceUtils.getConnection(dataSource)から接続しようとしましたが、MyBatisで使用されているものが見つかりました。これはMyBatis設定に問題があると思っていて、JpaTransactionManagerを使用できません。 DataSourceUtils.getConnectionを複数回呼び出しても、常に同じ接続が得られます。これは大丈夫です。いくつかは、(Tomcatが実際にそれを使用している場合、私は知りませんが:))私は春-楽器Tomcatのクラスローダを試してみたグーグルの後

部分のApplicationContext

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource"> 
    <property name="driverClassName" value="${database.driverClassName}"/> 
    <property name="url" value="${database.url}"/> 
    <property name="username" value="${database.username}"/> 
    <property name="password" value="${database.password}"/> 
</bean> 

<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory"/> 
</bean> 

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

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="configLocation" value="classpath:META-INF/mybatis/mybatis-config.xml" /> 
</bean> 

部分MyBatisのコンフィグ

<settings> 
    <setting name="cacheEnabled" value="false" /> 
    <setting name="useGeneratedKeys" value="false" /> 
    <setting name="defaultExecutorType" value="REUSE" /> 
    <setting name="lazyLoadingEnabled" value="false"/> 
</settings> 

部分的にpersistence.xml

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

答えて

34

私はここで解決策を見つけた:What transaction manager should I use for JBDC template When using JPA ?

私はDataSourceTransactionManager JpaTransactionManagerを使用していませんよ。
のJavaDoc http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/jpa/JpaTransactionManager.html

このトランザクションマネージャは、トランザクション内で直接データソースへのアクセス(同じデータソースでの作業、すなわち、プレーンJDBCコード)をサポートしています。これにより、JPAにアクセスするサービスと、(JPAを意識することなく)プレーンJDBCを使用するサービスを混在させることができます。アプリケーションコードは、DataSourceTransactionManager(つまりDataSourceUtils.getConnection(javax.sql.DataSource)またはTransactionAwareDataSourceProxyを経由する)と同じ単純な接続ルックアップパターンに固執する必要があります。 ベンダー固有のJpaDialectを設定する必要があることに注意してください。予想通り

は私が私のEntityManagerFactory設定すべての作品にjpaVendorAdapterを追加した後、JdbcTemplateクエリとMyBatisの両方が同じトランザクションで実行されます。 JavaDocに基づいて、jpaDialectは十分であるはずですが、それは午前4時です。ここで私は:)今

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> 
    <property name="persistenceUnitName" value="persistenceUnit"/> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="showSql" value="true" /> 
      <property name="generateDdl" value="true" /> 
      <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" /> 
     </bean> 
    </property> 
</bean> 
+0

はいちょうどjpaの方言を設定する 'emf.setJpaDialect(new HibernateJpaDialect());' –

-2

使用してみてください:JDBCレベル上で直接動作し

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

。すべての永続性抽象化(JPA/iBatisおよびJdbcTemplate)は最終的にJDBCを使用するため、最も高い共通レベルでトランザクションを処理する必要があります。

javax.persistence.EntityTransaction抽象化によってトランザクションを処理するJpaTransactionManagerを使用しています。明らかに、iBatisはJPAトランザクションを認識していないので、おそらくそれはその外部で動作します。

クラスローダー/計装魔法を使う必要はありません。

+0

残念ながら、これはうまくいかないようです。 – tewe

+0

"ベンダー固有のJpaDialectを設定する必要があります。 teweは問題を釘付けにしました - – chrismarx

4

ていることにしようとはしませんので、私はミックスでMyBatisのを持っていないが、teweはただのTransactionManagerにjpaDialectを追加すると、あまりにも仕事をしていません示唆したように。

<bean class="org.springframework.orm.jpa.JpaTransactionManager" 
    id="transactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    <property name="jpaDialect"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> 
    </property> 
</bean> 
関連する問題