com.impetus.kundera.persistence.EntityManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.impetus.kundera.persistence.EntityManagerImpl.java

Source

/*******************************************************************************
 * * Copyright 2012 Impetus Infotech.
 *  *
 *  * Licensed under the Apache License, Version 2.0 (the "License");
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *      http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 ******************************************************************************/
package com.impetus.kundera.persistence;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityNotFoundException;
import javax.persistence.EntityTransaction;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import javax.persistence.StoredProcedureQuery;
import javax.persistence.TransactionRequiredException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.transaction.UserTransaction;

import org.apache.commons.lang.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.impetus.kundera.Constants;
import com.impetus.kundera.KunderaException;
import com.impetus.kundera.cache.Cache;
import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.ClientResolverException;
import com.impetus.kundera.loader.ClientFactory;
import com.impetus.kundera.persistence.context.PersistenceCache;
import com.impetus.kundera.persistence.jta.KunderaJTAUserTransaction;
import com.impetus.kundera.query.KunderaTypedQuery;
import com.impetus.kundera.query.QueryImpl;

/**
 * The Class EntityManagerImpl.
 * 
 * @author animesh.kumar
 */
public class EntityManagerImpl implements EntityManager, ResourceManager {

    /** The Constant log. */
    private static Logger logger = LoggerFactory.getLogger(EntityManagerImpl.class);

    /** The factory. */
    private final EntityManagerFactory factory;

    /** The closed. */
    private boolean closed;

    /** Flush mode for this EM, default is AUTO. */
    private FlushModeType flushMode = FlushModeType.AUTO;

    /** Properties provided by user at the time of EntityManager Creation. */
    private Map<String, Object> properties;

    /** Properties provided by user at the time of EntityManager Creation. */
    private final PersistenceDelegator persistenceDelegator;

    /** Persistence Context Type (Transaction/ Extended) */
    private final PersistenceContextType persistenceContextType;

    /** Transaction Type (JTA/ RESOURCE_LOCAL) */
    private final PersistenceUnitTransactionType transactionType;

    private final PersistenceCache persistenceCache;

    private UserTransaction utx;

    private EntityTransaction entityTransaction;

    /**
     * Instantiates a new entity manager impl.
     * 
     * @param factory
     *            the factory
     * @param properties
     *            the properties
     */
    EntityManagerImpl(final EntityManagerFactory factory, final Map properties,
            PersistenceUnitTransactionType transactionType, final PersistenceContextType persistenceContextType) {
        this(factory, transactionType, persistenceContextType);
        this.properties = properties;

        getPersistenceDelegator().populateClientProperties(this.properties);
    }

    /**
     * Instantiates a new entity manager impl.
     * 
     * @param factory
     *            the factory
     */
    EntityManagerImpl(final EntityManagerFactory factory, final PersistenceUnitTransactionType transactionType,
            final PersistenceContextType persistenceContextType) {
        this.factory = factory;

        if (logger.isDebugEnabled()) {
            logger.debug("Creating EntityManager for persistence unit : " + getPersistenceUnit());
        }
        this.persistenceContextType = persistenceContextType;

        this.persistenceCache = new PersistenceCache((Cache) factory.getCache());
        this.persistenceCache.setPersistenceContextType(this.persistenceContextType);

        this.transactionType = transactionType;
        this.persistenceDelegator = new PersistenceDelegator(
                ((EntityManagerFactoryImpl) this.factory).getKunderaMetadataInstance(), this.persistenceCache);

        for (String pu : ((EntityManagerFactoryImpl) this.factory).getPersistenceUnits()) {
            this.persistenceDelegator.loadClient(pu, discoverClient(pu));
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Created EntityManager for persistence unit : " + getPersistenceUnit());
        }
    }

    /**
     * Make an instance managed and persistent.
     * 
     * @param entity
     * @throws EntityExistsException
     *             if the entity already exists. (If the entity already exists,
     *             the EntityExistsException may be thrown when the persist
     *             operation is invoked, or the EntityExistsException or another
     *             PersistenceException may be thrown at flush or commit time.)
     * @throws IllegalArgumentException
     *             if the instance is not an entity
     * @throws TransactionRequiredException
     *             if invoked on a container-managed entity manager of type
     *             PersistenceContextType.TRANSACTION and there is no
     *             transaction
     */
    @Override
    public final void persist(Object e) {
        checkClosed();
        checkTransactionNeeded();
        try {
            getPersistenceDelegator().persist(e);
        } catch (Exception ex) {
            // onRollBack.
            doRollback();
            throw new KunderaException(ex);
        }
    }

    /**
     * Merge the state of the given entity into the current persistence context.
     * 
     * @param entity
     * @return the managed instance that the state was merged to
     * @throws IllegalArgumentException
     *             if instance is not an entity or is a removed entity
     * @throws TransactionRequiredException
     *             if invoked on a container-managed entity manager of type
     *             PersistenceContextType.TRANSACTION and there is no
     *             transaction
     * @see javax.persistence.EntityManager#merge(java.lang.Object)
     */
    @Override
    public final <E> E merge(E e) {
        checkClosed();
        checkTransactionNeeded();
        try {
            return getPersistenceDelegator().merge(e);
        } catch (Exception ex) {
            // on Rollback
            doRollback();
            throw new KunderaException(ex);
        }
    }

    /**
     * Remove the entity instance.
     * 
     * @param entity
     * @throws IllegalArgumentException
     *             if the instance is not an entity or is a detached entity
     * @throws TransactionRequiredException
     *             if invoked on a container-managed entity manager of type
     *             PersistenceContextType.TRANSACTION and there is no
     *             transaction
     */
    @Override
    public final void remove(Object e) {
        checkClosed();
        checkTransactionNeeded();
        try {
            getPersistenceDelegator().remove(e);
        } catch (Exception ex) {
            // on rollback.
            doRollback();
            throw new KunderaException(ex);
        }
    }

    /**
     * Find by primary key. Search for an entity of the specified class and
     * primary key. If the entity instance is contained in the persistence
     * context it is returned from there.
     * 
     * @param entityClass
     * @param primaryKey
     * @return the found entity instance or null if the entity does not exist
     * @throws IllegalArgumentException
     *             if the first argument does not denote an entity type or the
     *             second argument is is not a valid type for that entitys
     *             primary key or is null
     * @see javax.persistence.EntityManager#find(java.lang.Class,
     *      java.lang.Object)
     */

    @Override
    public final <E> E find(Class<E> entityClass, Object primaryKey) {
        checkClosed();
        checkTransactionNeeded();
        return getPersistenceDelegator().findById(entityClass, primaryKey);
    }

    /**
     * Find by primary key, using the specified properties. Search for an entity
     * of the specified class and primary key. If the entity instance is
     * contained in the persistence context it is returned from there. If a
     * vendor-specific property or hint is not recognized, it is silently
     * ignored.
     * 
     * @param entityClass
     * @param primaryKey
     * @param properties
     *            standard and vendor-specific properties and hints
     * @return the found entity instance or null if the entity does not exist
     * @throws IllegalArgumentException
     *             if the first argument does not denote an entity type or the
     *             second argument is is not a valid type for that entitys
     *             primary key or is null
     * @see javax.persistence.EntityManager#find(java.lang.Class,
     *      java.lang.Object, java.util.Map)
     */
    @Override
    public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
        checkClosed();
        checkTransactionNeeded();

        // Store current properties in a variable for post-find reset
        Map<String, Object> currentProperties = getProperties();

        // Populate properties in client
        getPersistenceDelegator().populateClientProperties(properties);
        T result = find(entityClass, primaryKey);

        // Reset Client properties
        getPersistenceDelegator().populateClientProperties(currentProperties);
        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#find(java.lang.Class,
     * java.lang.Object, javax.persistence.LockModeType)
     */
    @Override
    public <T> T find(Class<T> paramClass, Object paramObject, LockModeType paramLockModeType) {
        checkClosed();
        throw new NotImplementedException("Lock mode type currently not supported by Kundera");
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#find(java.lang.Class,
     * java.lang.Object, javax.persistence.LockModeType, java.util.Map)
     */
    @Override
    public <T> T find(Class<T> arg0, Object arg1, LockModeType arg2, Map<String, Object> arg3) {
        checkClosed();
        throw new NotImplementedException("Lock mode type currently not supported by Kundera");
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#clear()
     */
    @Override
    public final void clear() {
        checkClosed();

        // TODO Do we need a client and persistenceDelegator close here?
        if (!PersistenceUnitTransactionType.JTA.equals(this.transactionType)) {
            getPersistenceDelegator().clear();
        }
    }

    @Override
    public final void close() {
        clear();

        getPersistenceDelegator().close();

        this.closed = true;
    }

    /**
     * Check if the instance is a managed entity instance belonging to the
     * current persistence context.
     * 
     * @param entity
     * @return boolean indicating if entity is in persistence context
     * @throws IllegalArgumentException
     *             if not an entity
     * @see javax.persistence.EntityManager#contains(java.lang.Object)
     */
    @Override
    public final boolean contains(Object entity) {
        checkClosed();

        return getPersistenceDelegator().contains(entity);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createQuery(java.lang.String)
     */
    @Override
    public final Query createQuery(String query) {
        checkClosed();
        checkTransactionNeeded();
        return getPersistenceDelegator().createQuery(query);
    }

    @Override
    public final void flush() {
        checkClosed();
        getPersistenceDelegator().doFlush();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getDelegate()
     */
    @Override
    public final Object getDelegate() {
        checkClosed();
        return getPersistenceDelegator().getDelegate();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createNamedQuery(java.lang.String)
     */
    @Override
    public final Query createNamedQuery(String name) {
        checkClosed();
        checkTransactionNeeded();
        return getPersistenceDelegator().createQuery(name);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createNativeQuery(java.lang.String)
     */
    @Override
    public final Query createNativeQuery(String sqlString) {
        checkClosed();
        return getPersistenceDelegator().createQuery(sqlString, getPersistenceUnit());
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createNativeQuery(java.lang.String,
     * java.lang.Class)
     */
    @Override
    public final Query createNativeQuery(String sqlString, Class resultClass) {
        checkClosed();
        checkTransactionNeeded();

        return getPersistenceDelegator().createNativeQuery(sqlString, resultClass);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createNativeQuery(java.lang.String,
     * java.lang.String)
     */
    @Override
    public final Query createNativeQuery(String sqlString, String resultSetMapping) {
        checkClosed();
        throw new NotImplementedException("ResultSetMapping currently not supported by Kundera. "
                + "Please use createNativeQuery(String sqlString, Class resultClass) instead.");
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getReference(java.lang.Class,
     * java.lang.Object)
     */
    @Override
    public final <T> T getReference(Class<T> entityClass, Object primaryKey) {
        checkClosed();
        throw new NotImplementedException("getReference currently not supported by Kundera");
    }

    @Override
    public final FlushModeType getFlushMode() {
        checkClosed();
        return this.flushMode;
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getTransaction()
     */
    @Override
    public final EntityTransaction getTransaction() {
        checkClosed();
        if (this.transactionType == PersistenceUnitTransactionType.JTA) {
            throw new IllegalStateException("A JTA EntityManager cannot use getTransaction()");
        }

        if (this.entityTransaction == null) {
            this.entityTransaction = new KunderaEntityTransaction(this);
        }
        return this.entityTransaction;
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#joinTransaction()
     */
    @Override
    public final void joinTransaction() {
        checkClosed();
        if (this.utx != null) {
            return;
        } else {
            throw new TransactionRequiredException("No transaction in progress");
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#lock(java.lang.Object,
     * javax.persistence.LockModeType)
     */
    @Override
    public final void lock(Object entity, LockModeType lockMode) {
        checkClosed();
        throw new NotImplementedException("lock currently not supported by Kundera");
    }

    /**
     * Refresh the state of the instance from the database, overwriting changes
     * made to the entity, if any.
     * 
     * @param entity
     * @throws IllegalArgumentException
     *             if the instance is not an entity or the entity is not managed
     * @throws TransactionRequiredException
     *             if invoked on a container-managed entity manager of type
     *             PersistenceContextType.TRANSACTION and there is no
     *             transaction
     * @throws EntityNotFoundException
     *             if the entity no longer exists in the database
     * @see javax.persistence.EntityManager#refresh(java.lang.Object)
     */
    @Override
    public final void refresh(Object entity) {
        checkClosed();

        checkTransactionNeeded();

        getPersistenceDelegator().refresh(entity);
    }

    /**
     * Refresh the state of the instance from the database, using the specified
     * properties, and overwriting changes made to the entity, if any. If a
     * vendor-specific property or hint is not recognized, it is silently
     * ignored.
     * 
     * @param entity
     * @param properties
     *            standard and vendor-specific properties and hints
     * @throws IllegalArgumentException
     *             if the instance is not an entity or the entity is not managed
     * @throws TransactionRequiredException
     *             if invoked on a container-managed entity manager of type
     *             PersistenceContextType.TRANSACTION and there is no
     *             transaction
     * @throws EntityNotFoundException
     *             if the entity no longer exists in the database
     * @see javax.persistence.EntityManager#refresh(java.lang.Object,
     *      java.util.Map)
     */
    @Override
    public void refresh(Object entity, Map<String, Object> properties) {
        checkClosed();

        // Store current properties in a variable for post-find reset
        Map<String, Object> currentProperties = getProperties();

        // Populate properties in client
        getPersistenceDelegator().populateClientProperties(properties);

        // Refresh state of entity
        refresh(entity);

        // Reset Client properties
        getPersistenceDelegator().populateClientProperties(currentProperties);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#lock(java.lang.Object,
     * javax.persistence.LockModeType, java.util.Map)
     */
    @Override
    public void lock(Object paramObject, LockModeType paramLockModeType, Map<String, Object> paramMap) {
        checkClosed();
        throw new NotImplementedException("Lock currently not supported by Kundera.");
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#refresh(java.lang.Object,
     * javax.persistence.LockModeType)
     */
    @Override
    public void refresh(Object paramObject, LockModeType paramLockModeType) {
        checkClosed();
        throw new NotImplementedException("Lock mode type currently not supported by Kundera.");

    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#refresh(java.lang.Object,
     * javax.persistence.LockModeType, java.util.Map)
     */
    @Override
    public void refresh(Object paramObject, LockModeType paramLockModeType, Map<String, Object> paramMap) {
        checkClosed();
        throw new NotImplementedException("LockModeType currently not supported by Kundera.");
    }

    /**
     * Remove the given entity from the persistence context, causing a managed
     * entity to become detached. Unflushed changes made to the entity if any
     * (including removal of the entity), will not be synchronized to the
     * database. Entities which previously referenced the detached entity will
     * continue to reference it.
     * 
     * @param entity
     * @throws IllegalArgumentException
     *             if the instance is not an entity
     * @see javax.persistence.EntityManager#detach(java.lang.Object)
     */
    @Override
    public void detach(Object entity) {
        checkClosed();

        if (entity == null) {
            throw new IllegalArgumentException("Entity is null, can't detach it.");
        }
        getPersistenceDelegator().detach(entity);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getLockMode(java.lang.Object)
     */
    @Override
    public LockModeType getLockMode(Object paramObject) {
        checkClosed();
        throw new NotImplementedException("Lock mode type currently not supported by Kundera.");
    }

    /**
     * Set an entity manager property or hint. If a vendor-specific property or
     * hint is not recognized, it is silently ignored.
     * 
     * @param propertyName
     *            name of property or hint
     * @param value
     * @throws IllegalArgumentException
     *             if the second argument is not valid for the implementation
     * @see javax.persistence.EntityManager#setProperty(java.lang.String,
     *      java.lang.Object)
     */
    @Override
    public void setProperty(String paramString, Object paramObject) {
        checkClosed();
        if (getProperties() == null) {
            this.properties = new HashMap<String, Object>();
        }

        this.properties.put(paramString, paramObject);
        getPersistenceDelegator().populateClientProperties(this.properties);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * javax.persistence.EntityManager#createQuery(javax.persistence.criteria
     * .CriteriaQuery)
     */
    @Override
    public <T> TypedQuery<T> createQuery(CriteriaQuery<T> paramCriteriaQuery) {
        checkClosed();

        return this.createQuery(CriteriaQueryTranslator.translate(paramCriteriaQuery),
                paramCriteriaQuery.getResultType());
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createQuery(java.lang.String,
     * java.lang.Class)
     */
    @Override
    public <T> TypedQuery<T> createQuery(String paramString, Class<T> paramClass) {
        Query q = createQuery(paramString);
        return onTypedQuery(paramClass, q);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#createNamedQuery(java.lang.String,
     * java.lang.Class)
     */
    @Override
    public <T> TypedQuery<T> createNamedQuery(String paramString, Class<T> paramClass) {
        Query q = createNamedQuery(paramString);
        return onTypedQuery(paramClass, q);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#unwrap(java.lang.Class)
     */
    @Override
    public <T> T unwrap(Class<T> paramClass) {
        checkClosed();
        throw new NotImplementedException("Unwrap currently not supported by Kundera");
    }

    @Override
    public final void setFlushMode(FlushModeType flushMode) {
        checkClosed();
        this.flushMode = flushMode;
        getPersistenceDelegator().setFlushMode(flushMode);
    }

    /**
     * Get the properties and hints and associated values that are in effect for
     * the entity manager. Changing the contents of the map does not change the
     * configuration in effect.
     * 
     * @return map of properties and hints in effect
     */
    @Override
    public Map<String, Object> getProperties() {
        checkClosed();
        return this.properties;
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getEntityManagerFactory()
     */
    @Override
    public EntityManagerFactory getEntityManagerFactory() {
        checkClosed();
        return this.factory;
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getCriteriaBuilder()
     */
    @Override
    public CriteriaBuilder getCriteriaBuilder() {
        checkClosed();
        return getEntityManagerFactory().getCriteriaBuilder();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#getMetamodel()
     */
    @Override
    public Metamodel getMetamodel() {
        checkClosed();
        return getEntityManagerFactory().getMetamodel();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.persistence.EntityManager#isOpen()
     */
    @Override
    public final boolean isOpen() {
        return !closed;
    }

    /**
     * Check closed.
     */
    private void checkClosed() {
        if (!isOpen()) {
            throw new IllegalStateException("EntityManager has already been closed.");
        }
    }

    private void checkTransactionNeeded() {
        onLookUp(transactionType);

        if ((getPersistenceContextType() != PersistenceContextType.TRANSACTION)
                || (getPersistenceDelegator().isTransactionInProgress())) {
            return;
        }
        throw new TransactionRequiredException(
                "no transaction is in progress for a TRANSACTION type persistence context");
    }

    private void onLookUp(PersistenceUnitTransactionType transactionType) {
        // TODO transaction should not be null;
        if (transactionType != null && transactionType.equals(PersistenceUnitTransactionType.JTA)) {
            if (this.entityTransaction == null) {
                this.entityTransaction = new KunderaEntityTransaction(this);
            }
            Context ctx;
            try {
                ctx = new InitialContext();

                this.utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction");

                if (this.utx == null) {
                    throw new KunderaException(
                            "Lookup for UserTransaction returning null for :{java:comp/UserTransaction}");
                }
                // TODO what is need to check?
                if (!(this.utx instanceof KunderaJTAUserTransaction)) {
                    throw new KunderaException("Please bind [" + KunderaJTAUserTransaction.class.getName()
                            + "] for :{java:comp/UserTransaction} lookup" + this.utx.getClass());
                }

                if (!this.entityTransaction.isActive()) {
                    this.entityTransaction.begin();
                    this.setFlushMode(FlushModeType.COMMIT);
                    ((KunderaJTAUserTransaction) this.utx).setImplementor(this);
                }

            } catch (NamingException e) {
                logger.error("Error during initialization of entity manager, Caused by:", e);
                throw new KunderaException(e);
            }

        }
    }

    /**
     * Returns Persistence unit (or comma separated units) associated with EMF.
     * 
     * @return the persistence unit
     */
    private String getPersistenceUnit() {
        return (String) getEntityManagerFactory().getProperties().get(Constants.PERSISTENCE_UNIT_NAME);
    }

    /**
     * Gets the persistence delegator.
     * 
     * @return the persistence delegator
     */
    PersistenceDelegator getPersistenceDelegator() {
        checkClosed();
        return this.persistenceDelegator;
    }

    /**
     * @return the persistenceContextType
     */
    private PersistenceContextType getPersistenceContextType() {
        return this.persistenceContextType;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.impetus.kundera.persistence.EntityImplementor#doCommit()
     */
    @Override
    public void doCommit() {
        checkClosed();
        this.entityTransaction.commit();
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.impetus.kundera.persistence.EntityImplementor#doRollback()
     */
    @Override
    public void doRollback() {
        checkClosed();
        if (this.entityTransaction != null) {
            this.entityTransaction.rollback();
        } else {
            getPersistenceDelegator().rollback();
        }
    }

    /**
     * Validates if expected result class is matching with supplied one, else
     * throws {@link IllegalArgumentException}
     * 
     * @param <T>
     *            object type
     * @param paramClass
     *            expected result class
     * @param q
     *            query
     * @return typed query instance.
     */
    private <T> TypedQuery<T> onTypedQuery(Class<T> paramClass, Query q) {
        if (paramClass.equals(((QueryImpl) q).getKunderaQuery().getEntityClass())
                || paramClass.equals(Object.class)) {
            return new KunderaTypedQuery<T>(q);
        }

        throw new IllegalArgumentException("Mismatch in expected return type. Expected:" + paramClass
                + " But actual class is:" + ((QueryImpl) q).getKunderaQuery().getEntityClass());
    }

    /**
     * Gets the client.
     * 
     * @param persistenceUnit
     *            the persistence unit
     * @return the client
     */
    private Client discoverClient(String persistenceUnit) {
        if (logger.isInfoEnabled()) {
            logger.info("Returning client instance for persistence unit {}.", persistenceUnit);
        }

        ClientFactory clientFactory = ((EntityManagerFactoryImpl) getEntityManagerFactory())
                .getClientFactory(persistenceUnit);
        if (clientFactory != null) {
            return clientFactory.getClientInstance();
        }
        throw new ClientResolverException("No client configured for persistence unit " + persistenceUnit + ".");
    }

    @Override
    public <T> EntityGraph<T> createEntityGraph(Class<T> arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public EntityGraph<?> createEntityGraph(String arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public StoredProcedureQuery createNamedStoredProcedureQuery(String arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Query createQuery(CriteriaUpdate arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Query createQuery(CriteriaDelete arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public StoredProcedureQuery createStoredProcedureQuery(String arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public StoredProcedureQuery createStoredProcedureQuery(String arg0, Class... arg1) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public StoredProcedureQuery createStoredProcedureQuery(String arg0, String... arg1) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public EntityGraph<?> getEntityGraph(String arg0) {
        //TODO: See https://github.com/impetus-opensource/Kundera/issues/457
        // Do nothing. Not yet implemented.
        return null;
    }

    @Override
    public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> arg0) {
        //TODO: See https://github.com/impetus-opensource/Kundera/issues/457
        // Do nothing. Not yet implemented.
        return null;
    }

    @Override
    public boolean isJoinedToTransaction() {
        //TODO: See https://github.com/impetus-opensource/Kundera/issues/457
        // Do nothing. Not yet implemented.
        return false;
    }

}