You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by "John Coleman (JIRA)" <ji...@apache.org> on 2012/11/14 02:48:12 UTC
[jira] [Updated] (TAP5-2027) EntityManagerObjectProvider always
provides the initial EntityManger proxy created
[ https://issues.apache.org/jira/browse/TAP5-2027?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
John Coleman updated TAP5-2027:
-------------------------------
Description:
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 code fixes the issue and is provided as-is, free and without copyright or warranty. This is more like a refactor because I have also replaced some depricated code. As a patch it also works just to remove the proxy class member variable and the if (proxy == null) condition.
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;
}
}
was:
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;
}
}
> 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.5, 5.3.6
> Reporter: John Coleman
> Labels: patch
>
> 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 code fixes the issue and is provided as-is, free and without copyright or warranty. This is more like a refactor because I have also replaced some depricated code. As a patch it also works just to remove the proxy class member variable and the if (proxy == null) condition.
> 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