2014-09-13 5 views
18

Hallo Ich benutze Hibernate JPA mit Feder und Mongodb und ich bin meine Anwendung auf Glassfish-4.0 ausgeführt.TransactionRequiredException Ausführen einer Update/Delete-Abfrage

Mein Serviceklasse ist

@Component 
public class Test { 

     @PersistenceContext 
      EntityManager em; 
      EntityManagerFactory emf; 

     @Transactional 
      public String persist(Details details){ 
       details.getUsername(); 
       details.getPassword(); 
       Query query = em.createNativeQuery("db.details.find(username= "+details.getUsername()+"& password= "+details.getPassword()); 
       em.getTransaction().begin(); 
       em.persist(details); 
       em.getTransaction().commit(); 
       em.flush(); 
       em.clear(); 
       em.close(); 
       query.executeUpdate(); 
       System.out.println("Sucessful!"); 
       return "persist";   
     } 
    } 

Und meine feder context.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:context="http://www.springframework.org/schema/context" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

    <context:component-scan base-package="com.javapapers.spring.mvc" /> 
    <context:annotation-config/> 
    <mvc:annotation-driven /> 
    <tx:annotation-driven transaction-manager="txManager" /> 
    <bean 
      class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
      <property name="prefix" value="/WEB-INF/view/" /> 
      <property name="suffix" value=".jsp" /> 
    </bean> 
    <bean id="entityManagerFactory" 
      class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> 
      <property name="persistenceUnitName" value="ogmTest"/> 
    </bean> 
    <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
    </bean> 
</beans> 

ich einige Änderungen im Code angewandt habe, aber sie ist keine Wirkung. Kann mir bitte jemand helfen, dies zu klären. Vielen Dank im Voraus.

+0

Versuchen Sie 'em.getTransaction() zu entfernen. Begin(); em.getTransaction(). Commit(); em.flush(); em.clear(); em.close(); 'sollte es sein zu springen, um Ihre Transaktion zu verwalten – kamil

+0

Danke für die Antwort Ich habe versucht mit dem, was Sie vorgeschlagen haben, aber ihre ist keine Änderung. – user41498

Antwort

1

Sie müssen sich keine Gedanken über die Anfangs- und Endtransaktion machen. Sie haben bereits die Annotation @Transactional angewendet, die die Transaktion beim Start der Methode intern öffnet und beim Beenden der Methode endet. Also nur erforderlich, um Ihr Objekt in der Datenbank zu erhalten.

@Transactional(readOnly = false, isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) 

     public String persist(Details details){ 
      details.getUsername(); 
      details.getPassword(); 
      Query query = em.createNativeQuery("db.details.find(username= "+details.getUsername()+"& password= "+details.getPassword()); 

      em.persist(details); 
      System.out.println("Sucessful!"); 
      return "persist";   
    } 

EDIT: Das Problem scheint mit der Konfigurationsdatei zu sein. Wenn Sie JPA verwenden, dann sollten Sie Ihre Konfigurationsdatei unter Konfiguration haben

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
    p:entityManagerFactory-ref="entityManagerFactory" /> 
<bean id="jpaAdapter" 
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" 
    p:database="ORACLE" p:showSql="true" /> 
<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    p:persistenceUnitName="YourProjectPU" 
    p:persistenceXmlLocation="classpath*:persistence.xml" 
    p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter"> 
    <property name="loadTimeWeaver"> 
     <bean 
      class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 
    </property> 
    <property name="persistenceProvider" ref="interceptorPersistenceProvider" /> 

</bean> 
+0

Hallo @sanket danke für die Antwort Ich habe Ihren Vorschlag ausprobiert Ich habe den gleichen Fehler. – user41498

+0

Ich habe meine Lösung bearbeitet. Siehe oben. Problem scheint mit Ihrer Konfigurationsdatei zu sein. – DeepInJava

+0

Es funktionierte ohne jpa Adapter durch Hinzufügen von @Transactional (readOnly = false, Isolation = Isolation.EFAULT, Propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}), aber es geht nicht zur Datenbank. Sammlung wird nicht in der Datenbank erstellt – user41498

32

Ich bin nicht sicher, ob dies helfen wird, du bist Situation (das heißt, wenn es vorhanden stillt), jedoch, nachdem die Bahn für eine Scheuer ähnliches Problem

Ich erstellte eine native Abfrage von einem Persistenz-Entitymanager, um ein Update durchzuführen.

Query query = entitymanager.createNativeQuery(queryString); 

ich folgende Fehlermeldung wurde empfangen:

caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query

Viele Lösungen vorschlagen @Transactional auf Ihre Methode hinzufügen. Nur dadurch wurde der Fehler nicht geändert.

Einige Lösungen schlagen vor, den Entitymanager nach einem EntityTransaction zu fragen, so dass Sie beginnen und sich verpflichten können. Diese wirft einen weiteren Fehler:

caused by: java.lang.IllegalStateException: Not allowed to create tranaction on shared EntityManager - use Spring transactions or EJB CMT instead

Ich habe dann versucht, eine Methode, die die meisten Websites sagen, ist für Manager Verwendung Anwendung verwaltete Einheit und nicht die Container verwaltet (was ich glaube, Frühling ist) und das war joinTransaction().

Mit @Transactional dekorieren die Methode und dann joinTransation() auf EntityManager Objekt kurz vor dem Aufruf query.executeUpdate() aufrufen und meine native Abfrage Update funktionierte.

Ich hoffe, dies hilft jemand anderen dieses Problem zu erfahren.

+2

Für diejenigen, die dies lesen, rufen Sie joinTransaction Sie tun em.joinTransaction(); (wo em ist Ihr EntityManager-Objekt) (auch eine der Schreibweisen der Funktion in der obigen Antwort ist schlecht, weshalb Sie die roten Squigglies in Eclipse erhalten, wenn Sie nur kopieren/einfügen. Stattdessen Sie können den Code in diesem Kommentar kopieren/einfügen Hier.) –

11

als Formular der Konfigurations-XML ist es klar, dass Sie Feder-basierte Transaktion verwenden werden. Bitte stellen Sie sicher, dass der Import, die Sie für @Transactional verwenden ist „org.springframework.transaction.annotation.Transactional“

in Ihrem Fall könnte es „javax.transaction sein.Transactional“

prost

Chetan Verma

+1

Wenn ich "org.springframework.transaction.annotation.Transactional" verwende funktioniert es gut – sendon1982

0

Nichts schien für mich zu arbeiten, bis ich merkte, dass meine Methode als public final statt nur public erklärt wurde. Der Fehler des final Schlüsselwort verursacht wurde. Entfernen es machte den Fehler weg.

+0

Die Bearbeitung hinzugefügt oder verbessert die Lösung und war daher nicht notwendig. Danke für (was du denkst) eine verbesserte Grammatik. Ich hätte einen produktiveren Ansatz vorgezogen. –

3

Wie wäre es @Transactional von Verfahren zur Klassenstufe zu verschieben? für mich gearbeitet in ähnlich gelagerten Fall, obwohl ich nicht 100% sicher bin, warum.

4

Ich habe auch dasselbe Problem konfrontiert, wenn ich mit Hibernate und Spring Jpa Data Repository arbeite. Ich habe vergessen, @Transactional auf Federdaten Repository-Methode zu platzieren.

Es funktioniert für mich nach Annotation der mit @Transactional.

+0

Das hat mir geholfen ... Ich brauchte sowohl "@Transactional" als auch "@Modifying" für die JPA-Repository-Methode. Das nur auf meiner Service-Methode (die das JPA-Repository aufruft) schien nicht genug zu sein. –

+1

Das hat mir geholfen. @Transactional war auch für die JPA-DAO-Repository-Methode erforderlich! Nicht zu fassen! Du bist ein Lebensretter, Satya P !! –

8

In meinem Fall hatte ich den falschen @Transaction importiert. Die richtige ist:

org.springframework.transaction.annotation.Transactional 

und nichtjavax.transaction.Transactional.

0

Nach der Integration von Spring 4 mit Hibernate 5 in mein Projekt und dieses Problem festgestellt, konnte ich verhindern, dass der Fehler durch Ändern der Art und Weise der Sitzung von sessionFactory.openSession() bis sessionFactory.getCurrentSession() angezeigt wird. der richtige Weg, um diesen Fehler zu erarbeiten, kann weiterhin die gleiche Sitzung für die verbindliche transaction.openssession wird immer eine neue Sitzung erstellen, die nicht wie der ehemalige eine Transaktion configed.using getCurrentSession und Hinzufügen von zusätzlichen Eigenschaft <property name="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property> funktioniert gut für mich .

0

Ich habe den gleichen Fehler.

Habe ich nur noch die @Transactional Annotation von javax.transaction.Transactional auf die Methode.

Verwandte Themen