John Coleman created TAP5-2027:
----------------------------------

             Summary: EntityManagerObjectProvider always provides the initial 
EntityManger proxy created
                 Key: TAP5-2027
                 URL: https://issues.apache.org/jira/browse/TAP5-2027
             Project: Tapestry 5
          Issue Type: Bug
          Components: tapestry-jpa
    Affects Versions: 5.3.6, 5.3.5
            Reporter: John Coleman


When persistence.xml defines multiple persistence units, classes injecting 
EntityManager with @PersistenceContext(unitName=value  crash because the 
entities associated with the PU in configuration are not recognised at runtime.

By placing trace in the code I established that the first EntityManager 
injected gets injected to all my other service classes even though I use 
different unitName= annotations.

The EntityManagerObjectProvider class contains a class variable proxy and works 
like a singleton always injecting the first EntityManager proxy class created 
for any later EntityManager injections.

The following patch fixes the issue and is provided as-is, free and without 
copyright or warranty:


package org.apache.tapestry5.internal.jpa;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.ObjectCreator;
import org.apache.tapestry5.ioc.ObjectLocator;
import org.apache.tapestry5.ioc.ObjectProvider;
import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
import org.apache.tapestry5.jpa.EntityManagerManager;

/**
 * A patched version to use PlasticProxyFactory and not cache the 
EntityManager as a class member.
 * @author John Coleman
 */
public class EntityManagerObjectProvider implements ObjectProvider
{

    /**
     * {@inheritDoc}
     */
    public <T> T provide(final Class<T> objectType, final AnnotationProvider 
annotationProvider,
            final ObjectLocator locator)
    {
        if (objectType.equals(EntityManager.class))
            return objectType.cast(getOrCreateProxy(annotationProvider, 
locator));

        return null;
    }

    private synchronized EntityManager getOrCreateProxy(
            final AnnotationProvider annotationProvider, final ObjectLocator 
objectLocator)
    {
            final PlasticProxyFactory proxyFactory = 
objectLocator.getService("PlasticProxyFactory",
              PlasticProxyFactory.class);

             final PersistenceContext annotation = annotationProvider
                            .getAnnotation(PersistenceContext.class);

            EntityManager proxy = 
proxyFactory.createProxy(EntityManager.class, new 
ObjectCreator<EntityManager>()
            {
                public EntityManager createObject()
                {
                    final EntityManagerManager entityManagerManager = 
objectLocator
                            .getService(EntityManagerManager.class);

                    return 
JpaInternalUtils.getEntityManager(entityManagerManager, annotation);
                }
            }, "<EntityManagerProxy>");

        return proxy;
    }

} 




--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to