javax.persistence.TransactionRequiredException in einer kleinen Facelet-Anwendung

7

Ich versuche, einige Werte in einer MySql-Datenbank aus einer kleinen Facelet-Anwendung beizubehalten, bekomme aber diesen Fehler. Ich hatte die gleiche Anwendung mit einer JPS-Seite und einem Servlet und es funktionierte in etwa mit der gleichen Logik, das ist das erste Mal, dass ich versuche, mit Facelets zu arbeiten, damit es vielleicht etwas albern ist, aber ich würde die Hilfe schätzen.

>

Danke

Fehler

%Vor%

index.xhtml

%Vor%

BookController.java

%Vor%

Book.java

%Vor%

percistence.xml

%Vor%     
Sergei 13.05.2013, 15:55
quelle

3 Antworten

24

Sie missbrauchen eine CDI-verwaltete Bean als Geschäftsservice. Es hat keine Hinweise auf das Transaktionsmanagement. Sie müssen Transaktionen manuell verwalten. Da dies normalerweise ein Problem ist und Sie anscheinend Glassfish verwenden, einen vollwertigen Java EE-Container, der EJBs unterstützt, möchten Sie lieber einen vollwertigen EJB dafür verwenden. Wenn EntityManager in einem EJB verwendet wird, verwaltet der Container vollständig DB-Transaktionen. Ein EJB-Methodenaufruf zählt als eine einzelne Transaktion (d. H. Wenn Sie mehrere DB-Abfragen auslösen und eine von ihnen fehlschlägt, wird alles automatisch zurückgesetzt).

Insgesamt scheinen Sie die Verantwortlichkeiten von Modell, Controller und Service zu mischen. Mach deine Entität nicht zu einer verwalteten Bean. Sie sollten außerdem absolut keine Geschäftslogik in einer Javabean-Getter-Methode ausführen (z. B. getBooks() ). Wenn in einer Iterationskomponente referenziert wird, wird es während jeder Iterationsrunde aufgerufen. Stellen Sie sich vor, dass Sie 100 Datensätze haben, dann wird die DB 100 mal getroffen. Das ist einfach ineffizient.

So sollte es aussehen:

Modell (die Entität):

%Vor%

Controller (die Backing-Bean):

%Vor%

Service (das EJB):

%Vor%

View (das Facelet; vereinfacht):

%Vor%

(Ihre Schaltflächen zum Bearbeiten und Löschen haben keinen Sinn ergeben, deshalb habe ich sie entfernt. Vielleicht möchten Sie sie in die Datentabelle einfügen)

Siehe auch:

BalusC 14.05.2013, 11:58
quelle
7

Fügen Sie einfach @Transactional Annotation zu Ihrer Methode hinzu, z. B.

%Vor%     
Alexander Volkov 06.05.2014 17:31
quelle
1

Das Javadoc für EntityManager#persist(Object) sagt

  

Wirft:   TransactionRequiredException - wenn auf einem aufgerufen   Vom Container verwalteter Entitätsmanager vom Typ   PersistenceContextType.TRANSACTION und es gibt keine Transaktion

Sie müssen EntityManager.html#getTransaction() aufrufen und beginnen Sie eine Transaktion , bevor Sie den Anruf fortsetzen (und einige der anderen Methoden). Vergessen Sie nicht auch commit oder rollback die Transaktion, wenn Sie fertig sind.

    
Sotirios Delimanolis 13.05.2013 16:01
quelle

Tags und Links