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% 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)
Fügen Sie einfach @Transactional
Annotation zu Ihrer Methode hinzu, z. B.
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.