Skip to content

Instantly share code, notes, and snippets.

@nacx
Created April 5, 2011 10:24
Show Gist options
  • Save nacx/903391 to your computer and use it in GitHub Desktop.
Save nacx/903391 to your computer and use it in GitHub Desktop.
OpenEntityManagerInterceptor to be used outside the web request scope
/**
* Abiquo community edition
* cloud management application for hybrid clouds
* Copyright (C) 2008-2010 - Abiquo Holdings S.L.
*
* This application is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC
* LICENSE as published by the Free Software Foundation under
* version 3 of the License
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* LESSER GENERAL PUBLIC LICENSE v.3 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package com.abiquo.api.spring.jpa;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.jpa.EntityManagerFactoryAccessor;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.request.WebRequestInterceptor;
/**
* OpenEntityManagerInView interceptor that is not coupled to the {@link WebRequestInterceptor}
* interface.
* <p>
* This interceptor should be used in beans that need the Hibernate Session and are out of the scope
* of Web requests, such as scheduled tasks.
*
* @author ibarrera
*/
public class OpenEntityManagerInterceptor extends EntityManagerFactoryAccessor implements
MethodInterceptor
{
/** The logger. */
private static final Logger LOGGER = LoggerFactory.getLogger(OpenEntityManagerInterceptor.class);
@Override
public Object invoke(final MethodInvocation invocation) throws Throwable
{
// Set the participate flag, to avoid binding again the EntityManagerHolder, and to avoid
// unbinding it if it is already part of another transaction
boolean participate = false;
if (TransactionSynchronizationManager.hasResource(getEntityManagerFactory()))
{
// If there is an active transaction, just reuse it
participate = true;
}
else
{
LOGGER.debug("Opening JPA EntityManager in OpenSessionInterceptor");
try
{
// If we are not part of another transaction, create the EntityManager and bind it
// to the TransactionSynchronizationManager
EntityManager em = createEntityManager();
TransactionSynchronizationManager.bindResource(getEntityManagerFactory(),
new EntityManagerHolder(em));
}
catch (PersistenceException ex)
{
throw new DataAccessResourceFailureException("Could not create JPA EntityManager",
ex);
}
}
Object ret = null;
try
{
ret = invocation.proceed();
}
finally
{
// Only unbind the resource if we are not participating in an existing transaction
if (!participate)
{
EntityManagerHolder emHolder =
(EntityManagerHolder) TransactionSynchronizationManager
.unbindResource(getEntityManagerFactory());
logger.debug("Closing JPA EntityManager in OpenSessionInterceptor");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
}
return ret;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment