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
015package org.apache.tapestry5.internal.jpa;
016
017import org.apache.tapestry5.jpa.EntityManagerManager;
018import org.apache.tapestry5.plastic.MethodAdvice;
019import org.apache.tapestry5.plastic.MethodInvocation;
020
021import javax.persistence.EntityManager;
022import javax.persistence.EntityTransaction;
023import javax.persistence.PersistenceContext;
024
025public 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}