Spring Boot + Spring-Daten JPA + Transaktionen funktionieren nicht ordnungsgemäß

8

Ich habe eine Spring Boot-Anwendung mit der Version 1.2.0 mit Spring-Boot-Starter-Data-JPA erstellt und verwende MySQL. Ich habe meine MySQL-Eigenschaften in der Datei application.properties korrekt konfiguriert.

Ich habe eine einfache JPA-Entität, ein Spring Data JPA-Repository und einen Service wie folgt:

%Vor%

Ich habe den folgenden JUnit-Test:

%Vor%

Die Erwartung hier ist, dass es keine Datensätze in PERSON-Tabelle einfügen sollte, da es Exception werfen wird, während 3. Person-Objekt eingefügt wird. Aber es wird nicht zurückgesetzt, zuerst werden 2 Datensätze eingefügt und festgeschrieben.

Dann dachte ich daran, schnell mit JPA EntityManager zu versuchen.

%Vor%

Dann bekomme ich javax.persistence.TransactionRequiredException: Kein transaktionaler EntityManager verfügbar Ausnahme.

Nachdem ich einige Zeit gegoogelt habe, begegne ich diesem JIRA-Thread Ссылка zum selben Thema.

Dann habe ich die Spring-Boot-Version auf 1.1.2 aktualisiert, um die Spring-Version älter als 4.0.6 zu machen.

Dann arbeitet em.save (person) wie erwartet, und die Transaktion funktioniert einwandfrei (bedeutet, dass alle DB-Einfügungen zurückgesetzt werden, wenn die RuntimeException aufgetreten ist).

Aber auch mit Spring 4.0.5 + Spring Data JPA 1.6.0-Versionen funktionieren Transaktionen nicht, wenn personRepository.save (person) anstelle von em.persist (person) .

Es scheint, dass Spring Data JPA-Repositorys die Transaktionen festschreiben.

Was vermisse ich? Wie können Service-Level @Transactional -Anmerkungen funktionieren?

PS:

Maven pom.xml

%Vor%

Anwendung.java

%Vor%     
K. Siva Prasad Reddy 19.02.2015, 12:32
quelle

3 Antworten

2

Ändern Sie die Transaktionsannotation in       @Transactional (rollbackFor = Exception.class)

    
Abhinay 04.06.2015 06:25
quelle
1

Von kommentieren von @m -dinum:

  

Machen Sie sowohl den PersonService public als auch die Methode, die Sie aufrufen.

Dies scheint für mehrere Benutzer den Trick getan zu haben. Dasselbe gilt auch für diese Antwort , unter Berufung auf manuelles Sprichwort :

  

Wenn Sie Proxies verwenden, sollten Sie die Annotation @Transactional anwenden   nur zu Methoden mit öffentlicher Sichtbarkeit. Wenn Sie mit Anmerkungen versehen sind,   private oder package-visible-Methoden mit der @ Transactional Annotation,   Es wird kein Fehler ausgegeben, aber die Methode mit Anmerkungen weist nicht das Problem auf   Transaktionseinstellungen konfiguriert Betrachten Sie die Verwendung von AspectJ (siehe   unten), wenn Sie nicht öffentliche Methoden kommentieren müssen.

    
eis 09.05.2017 09:43
quelle
0

Ich habe dies mit SpringBoot v1.2.0 und v1.5.2 getestet und alles funktioniert wie erwartet, Sie müssen den Entity Manager weder @Transactional (rollbackFor = Exception.class) verwenden.

Ich konnte nicht sehen, welchen Teil du falsch konfiguriert hast, alles scheint auf den ersten Blick gut, also poste ich einfach meine ganze Konfiguration als Referenz mit aktualisierten Annotationen und H2 Embedded Memory DB:

application.properties

%Vor%

pom.xml

%Vor%

Person.java

%Vor%

PersonRepository.java

%Vor%

PersonService.java

%Vor%

Anwendung.java

%Vor%

PersonServiceTest.java

%Vor%

* Die Datenbank wird für jeden Test gelöscht und neu initialisiert, so dass wir immer gegen einen bekannten Zustand validieren

    
Javier Sánchez 09.05.2017 08:56
quelle