deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gpetra...@apache.org
Subject svn commit: r1586690 - /deltaspike/site/trunk/content/jpa.mdtext
Date Fri, 11 Apr 2014 15:43:41 GMT
Author: gpetracek
Date: Fri Apr 11 15:43:41 2014
New Revision: 1586690

URL: http://svn.apache.org/r1586690
Log:
updated content

Modified:
    deltaspike/site/trunk/content/jpa.mdtext

Modified: deltaspike/site/trunk/content/jpa.mdtext
URL: http://svn.apache.org/viewvc/deltaspike/site/trunk/content/jpa.mdtext?rev=1586690&r1=1586689&r2=1586690&view=diff
==============================================================================
--- deltaspike/site/trunk/content/jpa.mdtext (original)
+++ deltaspike/site/trunk/content/jpa.mdtext Fri Apr 11 15:43:41 2014
@@ -326,6 +326,105 @@ Producer for the default EntityManager w
         }
     }
 
+# Extended Persistence Contexts
+
+Frameworks like MyFaces Orchestra provide a feature which allows keeping an `EntityManager`
across multiple requests. That means it isn't required to call `EntityManager#merge` to add
detached entities to the context. However, several application architectures don't allow such
an approach (due to different reasons like scalability). In theory that sounds nice and it
works pretty well for small to medium sized projects esp. if an application doesn't rely on
session replication in clusters. That also means that such an approach restricts your target
environment from the very beginning. One of the base problems is that an `EntityManager` isn't
serializable. Beans which are scoped in a normal-scoped CDI context have to be serializable.
So by default it isn't allowed by CDI to provide a producer-method which exposes e.g. a conversation
scoped `EntityManager` as it is. We **don't** recommend to use this approach and therefore
it isn't available out-of-the-box. However, if you really need 
 this approach to avoid calling `#merge` for your detached entities, it's pretty simple to
add this functionality.
+
+Usage of a simple `ExtendedEntityManager`
+
+    :::java
+    @Inject
+    private EntityManager entityManager;
+
+As you see the usage is the same. You **don't** have to use `ExtendedEntityManager` at the
injection point. It's just needed in the producer-method:
+
+
+Producer for the default Extended-`EntityManager` (no EE-Server):
+
+    :::java
+    //...
+    public class ExtendedEntityManagerProducer
+    {
+        //or manual bootstrapping
+        @PersistenceContext
+        private EntityManager entityManager;
+
+        @Produces
+        @RequestScoped
+        protected ExtendedEntityManager createEntityManager()
+        {
+            return new ExtendedEntityManager(this.entityManager);
+        }
+
+        protected void closeEntityManager(@Disposes ExtendedEntityManager entityManager)
+        {
+            if (entityManager.isOpen())
+            {
+                entityManager.close();
+            }
+        }
+    }
+
+
+Producer for the default Extended-`EntityManager` (EE-Server):
+
+
+    :::java
+    @ApplicationScoped
+    public class ExtendedEntityManagerProducer
+    {
+        @PersistenceUnit
+        private EntityManagerFactory entityManagerFactory;
+
+        @Produces
+        @Default
+        @RequestScoped
+        public ExtendedEntityManager create()
+        {
+            return new ExtendedEntityManager(this.entityManagerFactory.createEntityManager());
+        }
+
+        public void dispose(@Disposes @Default ExtendedEntityManager entityManager)
+        {
+            if (entityManager.isOpen())
+            {
+                entityManager.close();
+            }
+        }
+    }
+
+
+Implementation of a simple `ExtendedEntityManager`:
+
+
+    :::java
+    @Typed()
+    public class ExtendedEntityManager implements EntityManager, Serializable
+    {
+        private static final long serialVersionUID = 3770954229283539616L;
+ 
+        private transient EntityManager wrapped;
+ 
+        protected ExtendedEntityManager()
+        {
+        }
+ 
+        public ExtendedEntityManager(EntityManager wrapped)
+        {
+            this.wrapped = wrapped;
+        }
+ 
+        /*
+         * generated
+         */
+        //delegate all calls to this.wrapped - most IDEs allow to generate it
+    }
+
+This approach just works if it **doesn't come to serialization** of this wrapper e.g. in
case of session-replication.
+If those beans get serialized, you have to overcome this restriction by storing the persistence-unit-name
and recreate the `EntityManager` via `Persistence.createEntityManagerFactory(this.persistenceUnitName).createEntityManager();`
and sync it with the database before closing it on serialization.
+Furthermore, you have to intercept some methods of the `EntityManager` to merge detached
entities automatically if those entities get serialized as well. However, as mentioned before
**we don't recommend** such an approach.
+
+
 # JTA Support
 
 Per default the transaction-type used by `@Transactional`is 'RESOURCE_LOCAL'. If you configure
`transaction-type="JTA"`in the persistence.xml, you have to enable an alternative `TransactionStrategy`
in the beans.xml which is called `org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy`.



Mime
View raw message