You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by dr...@apache.org on 2011/03/10 00:00:51 UTC

svn commit: r1080050 - in /tapestry/tapestry5/trunk/tapestry-jpa/src: main/java/org/apache/tapestry5/internal/jpa/ main/java/org/apache/tapestry5/jpa/ test/java/org/apache/tapestry5/jpa/integration/ test/java/org/example/app/pages/ test/webapp/

Author: drobiazko
Date: Wed Mar  9 23:00:50 2011
New Revision: 1080050

URL: http://svn.apache.org/viewvc?rev=1080050&view=rev
Log:
TAP5-1472: Added ApplicationStatePersistenceStrategy for JPA entities.

Added:
    tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityApplicationStatePersistenceStrategy.java   (with props)
    tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java   (with props)
    tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaPersistenceConstants.java   (with props)
    tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/example/app/pages/SSOEntity.java   (with props)
    tapestry/tapestry5/trunk/tapestry-jpa/src/test/webapp/SSOEntity.tml
Modified:
    tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityPersistentFieldStrategy.java
    tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaModule.java
    tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaSymbols.java
    tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/apache/tapestry5/jpa/integration/JpaIntegrationTest.java

Added: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityApplicationStatePersistenceStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityApplicationStatePersistenceStrategy.java?rev=1080050&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityApplicationStatePersistenceStrategy.java (added)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityApplicationStatePersistenceStrategy.java Wed Mar  9 23:00:50 2011
@@ -0,0 +1,86 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.jpa;
+
+import org.apache.tapestry5.internal.services.SessionApplicationStatePersistenceStrategy;
+import org.apache.tapestry5.jpa.EntityManagerManager;
+import org.apache.tapestry5.services.ApplicationStateCreator;
+import org.apache.tapestry5.services.Request;
+
+public class EntityApplicationStatePersistenceStrategy extends
+        SessionApplicationStatePersistenceStrategy
+{
+    private final EntityManagerManager entityManagerManager;
+
+    public EntityApplicationStatePersistenceStrategy(final Request request,
+            final EntityManagerManager entityManagerManager)
+    {
+        super(request);
+
+        this.entityManagerManager = entityManagerManager;
+    }
+
+    @Override
+    public <T> T get(final Class<T> ssoClass, final ApplicationStateCreator<T> creator)
+    {
+        final Object persistedValue = getOrCreate(ssoClass, creator);
+
+        if (persistedValue instanceof PersistedEntity)
+        {
+            final PersistedEntity persisted = (PersistedEntity) persistedValue;
+
+            final Object restored = persisted.restore(entityManagerManager);
+
+            // shall we maybe throw an exception instead?
+            if (restored == null)
+            {
+                set(ssoClass, null);
+                return (T) getOrCreate(ssoClass, creator);
+            }
+
+            return (T) restored;
+        }
+
+        return (T) persistedValue;
+    }
+
+    @Override
+    public <T> void set(final Class<T> ssoClass, final T sso)
+    {
+        final String key = buildKey(ssoClass);
+        Object entity;
+
+        if (sso != null)
+        {
+            try
+            {
+                entity = JpaInternalUtils.convertApplicationValueToPersisted(entityManagerManager,
+                        sso);
+            }
+            catch (final RuntimeException ex)
+            {
+                // if entity not attached to an EntityManager yet, store it as usual sso
+                entity = sso;
+            }
+        }
+        else
+        {
+            entity = sso;
+        }
+
+        getSession().setAttribute(key, entity);
+    }
+
+}

Propchange: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityApplicationStatePersistenceStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityPersistentFieldStrategy.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityPersistentFieldStrategy.java?rev=1080050&r1=1080049&r2=1080050&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityPersistentFieldStrategy.java (original)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityPersistentFieldStrategy.java Wed Mar  9 23:00:50 2011
@@ -14,17 +14,8 @@
 
 package org.apache.tapestry5.internal.jpa;
 
-import java.util.Map;
-import java.util.Set;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.metamodel.EntityType;
-import javax.persistence.metamodel.Metamodel;
-
 import org.apache.tapestry5.internal.services.AbstractSessionPersistentFieldStrategy;
 import org.apache.tapestry5.jpa.EntityManagerManager;
-import org.apache.tapestry5.jpa.JpaConstants;
 import org.apache.tapestry5.services.Request;
 
 /**
@@ -45,18 +36,7 @@ public class EntityPersistentFieldStrate
     @Override
     protected Object convertApplicationValueToPersisted(final Object newValue)
     {
-        final EntityManager em = getEntityManagerFactory(newValue);
-
-        final EntityManagerFactory emf = em.getEntityManagerFactory();
-
-        final Map<String, Object> properties = emf.getProperties();
-
-        final String persistenceUnitName = (String) properties
-                .get(JpaConstants.PERSISTENCE_UNIT_NAME);
-
-        final Object id = emf.getPersistenceUnitUtil().getIdentifier(newValue);
-
-        return new PersistedEntity(newValue.getClass(), id, persistenceUnitName);
+        return JpaInternalUtils.convertApplicationValueToPersisted(entityManagerManager, newValue);
     }
 
     @Override
@@ -66,31 +46,4 @@ public class EntityPersistentFieldStrate
 
         return persisted.restore(entityManagerManager);
     }
-
-    private EntityManager getEntityManagerFactory(final Object entity)
-    {
-        final Map<String, EntityManager> entityManagers = entityManagerManager.getEntityManagers();
-
-        for (final EntityManager em : entityManagers.values())
-        {
-            final EntityManagerFactory emf = em.getEntityManagerFactory();
-
-            final Metamodel metamodel = emf.getMetamodel();
-
-            final Set<EntityType<?>> entities = metamodel.getEntities();
-
-            for (final EntityType<?> entityType : entities)
-            {
-                if (entityType.getJavaType() == entity.getClass())
-                {
-                    if (em.contains(entity)) { return em; }
-                }
-            }
-        }
-
-        throw new IllegalArgumentException(
-                String.format(
-                        "Failed persisting an entity in the session. The entity '%s' does not belong to any of the existing persistence contexts.",
-                        entity));
-    }
 }

Added: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java?rev=1080050&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java (added)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java Wed Mar  9 23:00:50 2011
@@ -0,0 +1,74 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.internal.jpa;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.tapestry5.jpa.EntityManagerManager;
+import org.apache.tapestry5.jpa.JpaConstants;
+
+public class JpaInternalUtils
+{
+    public static PersistedEntity convertApplicationValueToPersisted(
+            final EntityManagerManager entityManagerManager, final Object newValue)
+    {
+        final EntityManager em = getEntityManagerFactory(entityManagerManager, newValue);
+
+        final EntityManagerFactory emf = em.getEntityManagerFactory();
+
+        final Map<String, Object> properties = emf.getProperties();
+
+        final String persistenceUnitName = (String) properties
+                .get(JpaConstants.PERSISTENCE_UNIT_NAME);
+
+        final Object id = emf.getPersistenceUnitUtil().getIdentifier(newValue);
+
+        return new PersistedEntity(newValue.getClass(), id, persistenceUnitName);
+    }
+
+    private static EntityManager getEntityManagerFactory(
+            final EntityManagerManager entityManagerManager, final Object entity)
+    {
+        final Map<String, EntityManager> entityManagers = entityManagerManager.getEntityManagers();
+
+        for (final EntityManager em : entityManagers.values())
+        {
+            final EntityManagerFactory emf = em.getEntityManagerFactory();
+
+            final Metamodel metamodel = emf.getMetamodel();
+
+            final Set<EntityType<?>> entities = metamodel.getEntities();
+
+            for (final EntityType<?> entityType : entities)
+            {
+                if (entityType.getJavaType() == entity.getClass())
+                {
+                    if (em.contains(entity)) { return em; }
+                }
+            }
+        }
+
+        throw new IllegalArgumentException(
+                String.format(
+                        "Failed persisting an entity in the session. The entity '%s' does not belong to any of the existing persistence contexts.",
+                        entity));
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaModule.java?rev=1080050&r1=1080049&r2=1080050&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaModule.java Wed Mar  9 23:00:50 2011
@@ -23,6 +23,7 @@ import javax.persistence.spi.Persistence
 
 import org.apache.tapestry5.ValueEncoder;
 import org.apache.tapestry5.internal.jpa.CommitAfterWorker;
+import org.apache.tapestry5.internal.jpa.EntityApplicationStatePersistenceStrategy;
 import org.apache.tapestry5.internal.jpa.EntityManagerManagerImpl;
 import org.apache.tapestry5.internal.jpa.EntityManagerObjectProvider;
 import org.apache.tapestry5.internal.jpa.EntityManagerSourceImpl;
@@ -46,6 +47,10 @@ import org.apache.tapestry5.ioc.services
 import org.apache.tapestry5.ioc.services.RegistryShutdownHub;
 import org.apache.tapestry5.ioc.services.SymbolProvider;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.services.ApplicationStateContribution;
+import org.apache.tapestry5.services.ApplicationStateManager;
+import org.apache.tapestry5.services.ApplicationStatePersistenceStrategy;
+import org.apache.tapestry5.services.ApplicationStatePersistenceStrategySource;
 import org.apache.tapestry5.services.ComponentClassTransformWorker;
 import org.apache.tapestry5.services.PersistentFieldStrategy;
 import org.apache.tapestry5.services.ValueEncoderFactory;
@@ -82,7 +87,16 @@ public class JpaModule
     public static void provideEntityPersistentFieldStrategies(
             final MappedConfiguration<String, PersistentFieldStrategy> configuration)
     {
-        configuration.addInstance("entity", EntityPersistentFieldStrategy.class);
+        configuration.addInstance(JpaPersistenceConstants.ENTITY,
+                EntityPersistentFieldStrategy.class);
+    }
+
+    @Contribute(ApplicationStatePersistenceStrategySource.class)
+    public void provideApplicationStatePersistenceStrategies(
+            final MappedConfiguration<String, ApplicationStatePersistenceStrategy> configuration)
+    {
+        configuration.addInstance(JpaPersistenceConstants.ENTITY,
+                EntityApplicationStatePersistenceStrategy.class);
     }
 
     @Contribute(ComponentClassTransformWorker.class)
@@ -115,6 +129,7 @@ public class JpaModule
     {
         configuration.add(JpaSymbols.PROVIDE_ENTITY_VALUE_ENCODERS, "true");
         configuration.add(JpaSymbols.EARLY_START_UP, "true");
+        configuration.add(JpaSymbols.ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED, "true");
     }
 
     @Contribute(ValueEncoderSource.class)
@@ -157,6 +172,34 @@ public class JpaModule
         }
     }
 
+    @Contribute(ApplicationStateManager.class)
+    public static void provideApplicationStateContributions(
+            final MappedConfiguration<Class, ApplicationStateContribution> configuration,
+            final EntityManagerSource entityManagerSource,
+            @Symbol(JpaSymbols.PROVIDE_ENTITY_VALUE_ENCODERS)
+            final boolean entitySessionStatePersistenceStrategyEnabled)
+    {
+
+        if (!entitySessionStatePersistenceStrategyEnabled)
+            return;
+
+        for (final PersistenceUnitInfo info : entityManagerSource.getPersistenceUnitInfos())
+        {
+            final EntityManagerFactory emf = entityManagerSource.getEntityManagerFactory(info
+                    .getPersistenceUnitName());
+
+            for (final String className : info.getManagedClassNames())
+            {
+                final Metamodel metamodel = emf.getMetamodel();
+
+                final Class<?> clazz = loadClass(info, className);
+
+                configuration.add(clazz, new ApplicationStateContribution(
+                        JpaPersistenceConstants.ENTITY));
+            }
+        }
+    }
+
     @Startup
     public static void startupEarly(final EntityManagerSource entityManagerSource,
             @Symbol(JpaSymbols.EARLY_START_UP)

Added: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaPersistenceConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaPersistenceConstants.java?rev=1080050&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaPersistenceConstants.java (added)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaPersistenceConstants.java Wed Mar  9 23:00:50 2011
@@ -0,0 +1,27 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.jpa;
+
+import org.apache.tapestry5.PersistenceConstants;
+
+public class JpaPersistenceConstants
+{
+    /**
+     * If the field's value is a persistent JPA entity, its type and primary key is stored in the
+     * {@link org.apache.tapestry5.services.Session}. Otherwise,
+     * the value is stored as per {@link PersistenceConstants#SESSION}.
+     */
+    public static final String ENTITY = "entity";
+}

Propchange: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaPersistenceConstants.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaSymbols.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaSymbols.java?rev=1080050&r1=1080049&r2=1080050&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaSymbols.java (original)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/JpaSymbols.java Wed Mar  9 23:00:50 2011
@@ -20,6 +20,16 @@ public class JpaSymbols
 
     /**
      * If "true", then JPA will be started up at application launch, rather than lazily.
+     * 
+     * @since 5.3.0
      */
     public static final String EARLY_START_UP = "tapestry.jpa.early-startup";
+
+    /**
+     * If true, then "entity" persistence strategy is used to store JPA entities as
+     * {@code Session State Objects}.
+     * 
+     * @since 5.3.0
+     */
+    public static final String ENTITY_SESSION_STATE_PERSISTENCE_STRATEGY_ENABLED = "tapestry.jpa.entity-session-state-persistence-strategy-enabled";
 }

Modified: tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/apache/tapestry5/jpa/integration/JpaIntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/apache/tapestry5/jpa/integration/JpaIntegrationTest.java?rev=1080050&r1=1080049&r2=1080050&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/apache/tapestry5/jpa/integration/JpaIntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/apache/tapestry5/jpa/integration/JpaIntegrationTest.java Wed Mar  9 23:00:50 2011
@@ -14,7 +14,9 @@
 
 package org.apache.tapestry5.jpa.integration;
 
+import org.apache.tapestry5.internal.jpa.PersistedEntity;
 import org.apache.tapestry5.test.SeleniumTestCase;
+import org.example.app.entities.User;
 import org.testng.annotations.Test;
 
 public class JpaIntegrationTest extends SeleniumTestCase
@@ -62,4 +64,36 @@ public class JpaIntegrationTest extends 
         clickAndWait("link=set to transient");
         assertTextPresent("Failed persisting an entity in the session.");
     }
+
+    @Test
+    public void sso_entities()
+    {
+        open("/ssoentity");
+        assertEquals(getText("//span[@id='name']").length(), 0);
+        assertText("//span[@id='persistedEntityClassName']", User.class.getName());
+
+        clickAndWait("link=persist entity");
+        assertText("//span[@id='name']", "name");
+        assertText("//span[@id='persistedEntityClassName']", PersistedEntity.class.getName());
+
+        // can set back to null
+        clickAndWait("link=set to null");
+        assertEquals(getText("//span[@id='name']").length(), 0);
+        assertText("//span[@id='persistedEntityClassName']", User.class.getName());
+
+        clickAndWait("link=persist entity");
+        assertText("//span[@id='name']", "name");
+        assertText("//span[@id='persistedEntityClassName']", PersistedEntity.class.getName());
+
+        clickAndWait("link=delete");
+        assertEquals(getText("//span[@id='name']").length(), 0);
+        assertText("//span[@id='persistedEntityClassName']", User.class.getName());
+
+        clickAndWait("link=persist entity");
+        assertText("//span[@id='name']", "name");
+        assertText("//span[@id='persistedEntityClassName']", PersistedEntity.class.getName());
+
+        clickAndWait("link=set to transient");
+        assertText("//span[@id='persistedEntityClassName']", User.class.getName());
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/example/app/pages/SSOEntity.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/example/app/pages/SSOEntity.java?rev=1080050&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/example/app/pages/SSOEntity.java (added)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/example/app/pages/SSOEntity.java Wed Mar  9 23:00:50 2011
@@ -0,0 +1,81 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package org.example.app.pages;
+
+import java.util.List;
+
+import javax.persistence.PersistenceUnit;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SessionState;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.jpa.CommitAfter;
+import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.Session;
+import org.example.app.AppConstants;
+import org.example.app.entities.User;
+import org.example.app.services.UserDAO;
+
+public class SSOEntity
+{
+    @SessionState
+    @Property
+    private User user;
+
+    @Inject
+    private UserDAO userDAO;
+
+    @Inject
+    private Request request;
+
+    @CommitAfter
+    @PersistenceUnit(unitName = AppConstants.TEST_PERSISTENCE_UNIT)
+    void onPersistEntity()
+    {
+        final User user = new User();
+        user.setFirstName("name");
+
+        userDAO.add(user);
+
+        this.user = user;
+    }
+
+    void onSetToNull()
+    {
+        user = null;
+    }
+
+    void onSetToTransient()
+    {
+        user = new User();
+    }
+
+    @CommitAfter
+    @PersistenceUnit(unitName = AppConstants.TEST_PERSISTENCE_UNIT)
+    void onDelete()
+    {
+        final List<User> users = userDAO.findAll();
+
+        userDAO.delete(users.toArray(new User[0]));
+    }
+
+    public String getPersistedEntityClassName()
+    {
+        final Session session = request.getSession(true);
+
+        final Object value = session.getAttribute("sso:" + User.class.getName());
+
+        return value.getClass().getName();
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-jpa/src/test/java/org/example/app/pages/SSOEntity.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-jpa/src/test/webapp/SSOEntity.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-jpa/src/test/webapp/SSOEntity.tml?rev=1080050&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-jpa/src/test/webapp/SSOEntity.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-jpa/src/test/webapp/SSOEntity.tml Wed Mar  9 23:00:50 2011
@@ -0,0 +1,10 @@
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
+<body>
+	<p>entity name: <span id="name">${user?.firstName}</span></p>
+	<p>persisted entity class name: <span id="persistedEntityClassName">${persistedEntityClassName}</span></p>
+	<p><t:eventlink event="persistEntity">persist entity</t:eventlink></p>
+	<p><t:eventlink event="setToNull">set to null</t:eventlink></p>
+	<p><t:eventlink event="setToTransient">set to transient</t:eventlink></p>
+	<p><t:eventlink event="delete">delete</t:eventlink></p>
+</body>
+</html>
\ No newline at end of file