Seam Managed Persistence Contexts

Enabling the equivalent of 'session-in-view' with Seam

Overview

Seam comes with some built in components that support the 'session-in-view' pattern: Seam Managed Persistence Contexts. Actually it's much more correct than the 'session-in-view' pattern, but that's besides the point. Seam-managed persistence contexts can be used to eliminate lazy initialization exceptions when evaluating JSTL-EL expressions during view rendering as well as to bind all the activity in a conversation together under a single optimistic transaction.

See the docos here: http://docs.jboss.com/seam/latest/reference/en-US/html/persistence.html

There are a few subtle things that this doesn't explicitly cover:

  1. You can use the Seam-managed EntityManager in EJBs - This will eliminate some of the need for using merge(obj) because the EJBs can use the conversational EntityManager. However, in cases where you have a transaction-scoped EntityManager you will still need to merge or load objects that came from a different EntityManager.
  2. The Seam Application Framework classes are designed to use Seam-managed transactions

Steps

  1. Enable the TransactionalSeamPhaseListener in faces-config.xml
        <lifecycle>
            <!--
            We use the extended persistence context because we're going to take advantage of
            persistence contexts (hibernate sessions) that are conversation scoped (span transactions).
            This matches what the user may think is a "transaction", but in reality it may be many
            underlying database transactions.
            -->
            <phase-listener>org.jboss.seam.jsf.TransactionalSeamPhaseListener</phase-listener>
        </lifecycle>
    
  2. Enable a Seam-managed persistence context in components.xml
        <core:transactionListener/>
    
        <core:managed-persistence-context name="entityManager"
                                          auto-create="true"
                                          persistence-unit-jndi-name="java:/EntityManagerFactories/myDb"/>
    

    Assuming you have a persistence.xml something like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence">
        <persistence-unit name="myDb">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <jta-data-source>java:/MyDataSource</jta-data-source>
            <properties>
                <!-- Register the entity manager factory in JNDI so SEAM can use it. -->
                <property name="jboss.entity.manager.factory.jndi.name"
                          value="java:/EntityManagerFactories/myDb"/>
                <!-- Comment this out once we switch to true migration -->
                <!--<property name="hibernate.hbm2ddl.auto" value="create"/>-->
                <property name="hibernate.show_sql" value="false"/>
                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
                <property name="com.intellij.javaee.persistence.datasource" value="Mysql local"/>
            </properties>
        </persistence-unit>
    </persistence>
    
  3. Inject the Seam-managed EntityManager into your components using @In (instead of the usual @PersistenceContext), for example:
    @Stateless
    public class MyEJBImpl implements MyEJB
    {
        ...
    
        @In
        private EntityManager entityManager;
        ...
    }
    

But session-in-view is an anti-pattern, isn't it?

Yes, it is! However what Seam is doing is not really session-in-view. Actually Seam provides two sessions:

  1. A session that exists during the postback phases of JSF.
  2. A separate session used for rendering the next view.

This eliminates the problem with the ordinary session-in-view pattern where the rendering part of the web request cycle affects the persistence context / database transaction done in the controller. Incidentally this is why a session-in-view design should never be used in an enterprise-class application (IMO) because presumably the user thinks their data is actually important and would not like an inconsistent database.

Labels

seam seam Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.