Pourquoi ma transaction est pas active? javax.la persistance.TransactionRequiredException: l'Exécution d'une mise à jour/suppression de requête
J'ai un Ressort de Service Web (Spring-WS) de l'application que je suis en train de configurer à utiliser. La pile que j'utilise est comme suit
Spring 3
Spring-WS
JPA with Hibernate as the provider
JBoss 7.1*
L'application est configurée comme suit:
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 - Entity manager et un gestionnaire de Transactions
<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 - De charger le spring.xml fichier ci-dessus
<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"/>
Dans ma classe DAO, j'ai la définition suivante pour l'entityManager.
@PersistenceContext(type=PersistenceContextType.TRANSACTION, unitName="myPersistenceUnit")
protected EntityManager entityManager;
@Transactional
public void updateProduct(Product product) {
// Save the document to the database
update(product);
}
La méthode de mise à jour ci-dessus appelle tout simplement une méthode générique avec un appel à entityManager.merge(object);
Maintenant, quand je test la dessus je trouve que ça marche si je suis de lecture à partir de la base de données, mais il ne fonctionne pas si je suis en train d'écrire dans la base de données (c'est à dire créer ou mettre à jour).
Si j'essaie d'écrire à l'-je obtenir de l'exception suivante:
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)
Je suppose que le fait que je peux lire à partir de la base de données, cela signifie que quelque chose est incorrect dans la configuration du gestionnaire de transactions. Des idées?
Modifier
OK je viens de re-lire ce qui précède et remarqué que le dernier bit est un peu mal. L'exception que j'ai montré ci-dessus ne se produit que si j'utilise JPQL d'émettre une instruction de mise à Jour à l'aide de entityManager.createQuery
. Si j'essaie de mettre à jour l'entité à l'aide de entityManager.merge()
rien de ce qui se passe réellement. Aucune exception n'est retourné, mais la ligne n'est pas mis à jour.
- Une question bête peut-être, mais comment faites-vous appel à
updadeProduct
? Est-il par l'interface?
Vous devez vous connecter pour publier un commentaire.
Lorsque vous marquez une méthode comme @Transactional vous comptez sur JTA, mais - comme l'a déclaré altanis - pourtant, vous définissez votre unité de persistance du type d'opération que RESOURCE_LOCAL qui n'est pas JTA.
1) Si vous souhaitez utiliser gérée par le conteneur des opérations puis changez le type de transaction, de définir la source de données comme source de données JTA dans JBoss et le changement non-jta-data-source à jta-data-source
2) Si vous souhaitez gérer vos propres opérations, puis garder les persistence.xml et de la source des données définition, puisqu'elle est, mais avant tout persist, merge, les opérations de suppression de démarrer une transaction en appelant l'entitymanager.getTransaction().begin() et à la fin de la business unit, appelez l'entitymanager.getTransaction().commit() ou l'entitymanager.getTransaction().rollback(). Dans ce cas, puisque vous êtes à la gestion des opérations vous-même, alors il semble y avoir aucun point de départ d'une transaction JTA avec @Transactional dans updateProduct().
essayer de changer de transaction-type="RESOURCE_LOCAL" transaction-type="JTA" dans persistence.xml. Aussi, vous pouvez avoir besoin de supprimer l'élément de persistence.xml.