Disable Seam Managed Transactions

Für CDI- und JSF-basierte Anwendungen bietet es sich an, den Programmkomfort durch Einsatz einer Portable Extension wie JBoss Seam zu erhöhen. Damit erhält man u. a.:

  • Seam Managed Persistence Context (aus dem Modul Seam Persistence)
    Damit lässt sich ein ConversationScoped EntityManager in CDI Beans injizieren, der – da Conversation-gebunden – über mehrere Requests offen gehalten werden kann.
  • Injektionsmöglichkeiten innerhalb von Faces Converters und Faces Validators (aus dem Modul Seam Faces)
    Damit können beliebige CDI Beans bspw. in einen Konverter injiziert werden, um von dort DB-Zugriff o. ä. zu erhalten.

Zur Integration der Extensions reicht es, die entsprechenden Bibliotheken in den Classpath zu legen, z. B. mittels Maven:

   <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.jboss.seam</groupId>
        <artifactId>seam-bom</artifactId>
        <version>3.1.0.Final</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.jboss.seam.international</groupId>
      <artifactId>seam-international</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam.international</groupId>
      <artifactId>seam-international-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam.faces</groupId>
      <artifactId>seam-faces-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam.faces</groupId>
      <artifactId>seam-faces</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam.persistence</groupId>
      <artifactId>seam-persistence-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.seam.persistence</groupId>
      <artifactId>seam-persistence</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.jboss.solder</groupId>
      <artifactId>solder-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.solder</groupId>
      <artifactId>solder-impl</artifactId>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

So weit, so gut … aber:
Seam Persistence und Seam Faces haben eine unangenehme (man könnte auch sagen, unverschämte) Eigenschaft: Sie starten für einen Web-Request automatisch eine Transaktion und beenden diese am Request-Ende wieder. Dadurch wird das Prinzip der statusbehafteten, transparenten Persistenz zunichte gemacht, bei der man – wie oben schon angesprochen – einen EntityManager über mehrere Requests offen hält, darin durchaus auch schon Datenänderungen sammelt und diese Änderungen am Ende der Conversation durch das explizite Öffnen und Schließen einer Transaktion dauerhaft wegschreibt.
Es gilt also, den Transaktions-Automatismus von Seam zu unterdrücken. Dies gelingt wie wolgt:

  • Seam Persistence etabliert einen Servlet-Listener (org.jboss.seam.transaction.TransactionServletListener).
    Er wird mit dem folgenden Context Parameter in web.xml abgeschaltet:<!– Disable Seam Persistence TransactionServletListener –>

     <context-param>
         <param-name>org.jboss.seam.transaction.disableListener</param-name>
         <param-value>true</param-value>
    </context-param>
    
  • Seam Faces setzt einen Phase Listener zum gleichen Zweck ein (org.jboss.seam.faces.transaction.TransactionPhaseListener). Den bekommt man über den in Seam Faces neuerdings vorhandenen ViewConfig-Mechanismus zum Schweigen. Dazu einfach das folgende Interface in die Anwendung integrieren:
    public interface ViewConfiguration
    {
              static enum ViewConfigurationParameter
        {
            @ViewPattern("/*")
            @SeamManagedTransaction(SeamManagedTransactionType.DISABLED)
            ALL;
        }
    }

    Die Namen des Interfaces und des darin enthaltenen Enums sind belanglos. Wichtig ist nur, dass das Interface von CDI erkannt wird, d. h. im Dunstkreis eines beans.xml liegt.

Das herauszufinden, hat mich ca. einen Tag gekostet, insbesondere, da die Dokumentation zu den beiden Features derzeit i. W. durch Abwesenheit glänzt. Ich halte es zudem auch für bedenklich, dass die beiden Seam-Module hinterrücks (hinterlistig?) die Transaktionssteuerung übernehmen wollen. Ein solches Feature sollte IMHO nicht per Default aktiv sein.

Advertisements

Über Dirk Weil
Dirk Weil ist seit 1998 als Berater im Bereich Java tätig. Als Geschäftsführer der GEDOPLAN GmbH in Bielefeld ist er für die Konzeption und Realisierung von Informationssystemen auf Basis von Java EE verantwortlich. Seine langjährige Erfahrung in der Entwicklung anspruchsvoller Unternehmenslösungen machen ihn zu einem kompetenten Ansprechpartner und anerkannten Experten auf dem Gebiet Java EE. Er ist Autor in Fachmagazinen, hält Vorträge und leitet Seminare und Workshops aus einem eigenen Java-Curriculum.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: