001/****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one   *
003 * or more contributor license agreements.  See the NOTICE file *
004 * distributed with this work for additional information        *
005 * regarding copyright ownership.  The ASF licenses this file   *
006 * to you under the Apache License, Version 2.0 (the            *
007 * "License"); you may not use this file except in compliance   *
008 * with the License.  You may obtain a copy of the License at   *
009 *                                                              *
010 *   http://www.apache.org/licenses/LICENSE-2.0                 *
011 *                                                              *
012 * Unless required by applicable law or agreed to in writing,   *
013 * software distributed under the License is distributed on an  *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015 * KIND, either express or implied.  See the License for the    *
016 * specific language governing permissions and limitations      *
017 * under the License.                                           *
018 ****************************************************************/
019package org.apache.james.mailbox.jpa;
020
021import javax.persistence.EntityManager;
022import javax.persistence.EntityManagerFactory;
023import javax.persistence.EntityTransaction;
024import javax.persistence.PersistenceException;
025
026import org.apache.james.mailbox.exception.MailboxException;
027import org.apache.james.mailbox.store.transaction.TransactionalMapper;
028
029/**
030 * JPA implementation of TransactionMapper. This class is not thread-safe!
031 *
032 */
033public abstract class JPATransactionalMapper extends TransactionalMapper {
034
035    protected EntityManagerFactory entityManagerFactory;
036    protected EntityManager entityManager;
037    
038    public JPATransactionalMapper(final EntityManagerFactory entityManagerFactory) {
039        this.entityManagerFactory = entityManagerFactory;
040    }
041
042    /**
043     * Return the currently used {@link EntityManager} or a new one if none exists.
044     * 
045     * @return entitymanger
046     */
047    public EntityManager getEntityManager() {
048        if (entityManager != null)
049            return entityManager;
050        entityManager = entityManagerFactory.createEntityManager();
051        return entityManager;
052    }
053
054    /**
055     * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#begin()
056     */
057    protected void begin() throws MailboxException {
058        try {
059            getEntityManager().getTransaction().begin();
060        } catch (PersistenceException e) {
061            throw new MailboxException("Begin of transaction failed", e);
062        }
063    }
064
065    /**
066     * Commit the Transaction and close the EntityManager
067     */
068    protected void commit() throws MailboxException {
069        try {
070            getEntityManager().getTransaction().commit();
071        } catch (PersistenceException e) {
072            throw new MailboxException("Commit of transaction failed",e);
073        }
074    }
075
076    /**
077     * @see org.apache.james.mailbox.store.transaction.TransactionalMapper#rollback()
078     */
079    protected void rollback() throws MailboxException {
080        EntityTransaction transaction = entityManager.getTransaction();
081        // check if we have a transaction to rollback
082        if (transaction.isActive()) {
083            getEntityManager().getTransaction().rollback();
084        }
085    }
086
087    /**
088     * Close open {@link EntityManager}
089     */
090    public void endRequest() {
091        if (entityManager != null) {
092            if (entityManager.isOpen())
093                entityManager.close();
094            entityManager = null;
095        }
096    }
097
098    
099}