    001    // Copyright 2011, 2012 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    // http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.jpa;
    016
    017    import org.apache.tapestry5.jpa.EntityManagerManager;
    018    import org.apache.tapestry5.plastic.MethodAdvice;
    019    import org.apache.tapestry5.plastic.MethodInvocation;
    020
    021    import javax.persistence.EntityManager;
    022    import javax.persistence.EntityTransaction;
    023    import javax.persistence.PersistenceContext;
    024
    025    public class CommitAfterMethodAdvice implements MethodAdvice
    026    {
    027        private final EntityManagerManager manager;
    028
    029        private final PersistenceContext annotation;
    030
    031        public CommitAfterMethodAdvice(final EntityManagerManager manager, PersistenceContext annotation)
    032        {
    033            this.manager = manager;
    034            this.annotation = annotation;
    035        }
    036
    037        public void advise(final MethodInvocation invocation)
    038        {
    039            final EntityTransaction transaction = getTransaction();
    040
    041            if (transaction != null && !transaction.isActive())
    042            {
    043                transaction.begin();
    044            }
    045
    046            try
    047            {
    048                invocation.proceed();
    049            } catch (final RuntimeException e)
    050            {
    051                if (transaction != null && transaction.isActive())
    052                {
    053                    rollbackTransaction(transaction);
    054                }
    055
    056                throw e;
    057            }
    058
    059            // Success or checked exception:
    060
    061            if (transaction != null && transaction.isActive())
    062            {
    063                transaction.commit();
    064            }
    065
    066        }
    067
    068        private void rollbackTransaction(EntityTransaction transaction)
    069        {
    070            try
    071            {
    072                transaction.rollback();
    073            } catch (Exception e)
    074            { // Ignore
    075            }
    076        }
    077
    078        private EntityTransaction getTransaction()
    079        {
    080            EntityManager em = JpaInternalUtils.getEntityManager(manager, annotation);
    081
    082            if (em == null)
    083                return null;
    084
    085            return em.getTransaction();
    086        }
    087
    088    }