2

使用するように構成しようとしているSpringWebService(Spring-WS)アプリケーションがあります。私が使用しているスタックは次のとおりです

Spring 3
Spring-WS
JPA with Hibernate as the provider
JBoss 7.1*

アプリケーションは次のように構成されています。

persistence.xml

<persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:jboss/datasources/myDataSource</jta-data-source>
        <non-jta-data-source>java:jboss/datasources/myDataSource</non-jta-data-source>
        <class>myPackage.MyClass</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>           
            <property name="hibernate.connection.autocommit" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="validate"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
            <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/>
            <property name="hibernate.search.default.indexBase" value="./lucene/indexes"/>
            <property name="hibernate.search.default.batch.merge_factor" value="10"/>
            <property name="hibernate.search.default.batch.max_buffered_docs" value="10"/>
        </properties>
    </persistence-unit>

spring.xml-エンティティマネージャーおよびトランザクションマネージャー

<context:annotation-config/>

    <context:component-scan base-package="com.mypackage"/>

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <!-- Live database entity and transaction managers -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="myDataSource">

        <property name="persistenceUnitName" value="myPersistenceUnit" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
        p:entityManagerFactory-ref="entityManagerFactory" />

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

Web.xml-上記のspring.xmlファイルをロードするには

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/app-config.xml
            /WEB-INF/spring.xml
            /WEB-INF/spring-datasources.xml
         </param-value>   
     </context-param>

spring-datasources.xml

<jee:jndi-lookup id="myDataSource" jndi-name="java:jboss/datasources/myDataSource"/>

私のDAOクラスでは、entityManagerに対して次の定義があります。

@PersistenceContext(type=PersistenceContextType.TRANSACTION, unitName="myPersistenceUnit")
protected EntityManager entityManager;

@Transactional
    public void updateProduct(Product product) {

        //  Save the document to the database
        update(product);
    }

上記のupdateメソッドは、次の呼び出しを使用してジェネリックメソッドを呼び出すだけです。entityManager.merge(object);

上記をテストすると、データベースから読み取っている場合は機能しますが、データベースに書き込んでいる場合(つまり、作成または更新)は機能しません。に書き込もうとすると、次の例外が発生します。

javax.persistence.TransactionRequiredException: Executing an update/delete query
   at org.hibernate.ejb.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:96)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:310)
   at $Proxy96.executeUpdate(Unknown Source)

データベースから読み取ることができるという事実は、トランザクションマネージャーの構成に問題があることを意味していると思います。何か案は?

編集

OK、上記を読み直して、最後のビットが少し間違っていることに気づきました。上に示した例外は、JPQLを使用して。を使用してUpdateステートメントを発行した場合にのみ発生しentityManager.createQueryます。何も使用せずにエンティティを更新しようとすると、entityManager.merge()実際には何も起こりません。例外は返されませんが、行は更新されません。

4

2 に答える 2

4

メソッドを @Transactional としてマークすると、JTA に頼っていますが、altanis が述べているように、永続化ユニットのトランザクション タイプを JTA ではない RESOURCE_LOCAL として定義します。

1) コンテナ管理のトランザクションを使用したい場合は、トランザクション タイプを変更し、JBoss でデータソースを JTA データソースとして定義し、non-jta-data-source を jta-data-source に変更します。

2) 独自のトランザクションを管理する場合は、persistence.xml とデータソースの定義をそのまま保持しますが、永続化、マージ、削除操作の前に、entitymanager.getTransaction().begin() を呼び出してトランザクションを開始し、最後にビジネス ユニットの場合は、entitymanager.getTransaction().commit() または entitymanager.getTransaction().rollback() を呼び出します。この場合、自分でトランザクションを管理しているため、updateProduct() で @Transactional を使用して JTA トランザクションを開始しても意味がないように思われます。

于 2012-10-05T21:06:56.927 に答える
1

persistence.xml で transaction-type="RESOURCE_LOCAL" を transaction-type="JTA" に変更してみてください。また、persistence.xml から要素を削除する必要がある場合もあります。

于 2012-06-13T13:55:08.680 に答える