Looks like we need to discuss the "copying annotations to proxies with
plastic" issue again. I just tried to migrate tapestry-jpa to plastic and
experience some problems. I didn't commit it because I don't want to break
the build, so here is an example of CommitAfterMethodAdvice.

public class CommitAfterMethodAdvice implements MethodAdvice
{

    private final EntityManagerManager manager;

    public CommitAfterMethodAdvice(final EntityManagerManager manager)
    {
        super();
        this.manager = manager;
    }

    public void advise(final MethodInvocation invocation)
    {
        final EntityTransaction transaction = getTransaction(invocation);

        if (transaction != null && !transaction.isActive())
        {
            transaction.begin();
        }

        try
        {
            invocation.proceed();
        }
        catch (final RuntimeException e)
        {
            if (transaction != null && transaction.isActive())
            {
                transaction.rollback();
            }

            throw e;
        }

        // Success or checked exception:

        if (transaction != null && transaction.isActive())
        {
            transaction.commit();
        }

    }

    private EntityTransaction getTransaction(final MethodInvocation
invocation)
    {
        final PersistenceContext annotation =
invocation.getAnnotation(PersistenceContext.class);

        EntityManager em = JpaInternalUtils.getEntityManager(manager,
annotation);

        if (em == null)
            return null;

        return em.getTransaction();
    }

}


The problem is invocation.getAnnotation(PersistenceContext.class) which
always returns null. If I recall it correctly, Plastic doesn't copy
annotations to proxies, so that my DAO proxies loose the annotations. Here
is the DAO:

public interface UserDAO
{
    @CommitAfter
    @PersistenceContext(unitName = AppConstants.TEST_PERSISTENCE_UNIT)
    void add(User user);

    .....
}

What I don't get, is why PlasticClass is able to see the
@ CommitAfter annotation, but the MethodInvocation of the corresponding
advise not. Here is the Worker.

public class CommitAfterWorker implements ComponentClassTransformWorker2
{
    private final CommitAfterMethodAdvice advice;

    public CommitAfterWorker(final EntityManagerManager manager)
    {
        advice = new CommitAfterMethodAdvice(manager);
    }

    public void transform(PlasticClass plasticClass, TransformationSupport
support, MutableComponentModel model)
    {
        for (final PlasticMethod method :
plasticClass.getMethodsWithAnnotation(CommitAfter.class))
        {
            method.addAdvice(advice);
        }
    }
}


Any ideas?

-- 
Best regards,

Igor Drobiazko
http://tapestry5.de

Reply via email to