All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fabric3.jpa.runtime.proxy.EntityManagerServiceImpl Maven / Gradle / Ivy

/*
 * Fabric3
 * Copyright (c) 2009-2015 Metaform Systems
 *
 * 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.
 * Portions originally based on Apache Tuscany 2007
 * licensed under the Apache 2.0 license.
 */
package org.fabric3.jpa.runtime.proxy;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;

import org.oasisopen.sca.annotation.Reference;

import org.fabric3.jpa.runtime.emf.EntityManagerFactoryCache;

/**
 * Manages a cache of EntityManagers.
 * 

* EntityManager instances (and their underlying Hibernate Sessions) are cached for the duration of the associated JTA transaction and closed when the * transaction commits or rolls back. */ public class EntityManagerServiceImpl implements EntityManagerService { // a cache of entity managers keyed by Transaction and persistence unit name private Map cache = new ConcurrentHashMap<>(); // tracks which entity managers have joined transactions private EntityManagerFactoryCache emfCache; public EntityManagerServiceImpl(@Reference EntityManagerFactoryCache emfCache) { this.emfCache = emfCache; } public EntityManager getEntityManager(String unitName, HibernateProxy proxy, Transaction transaction) throws EntityManagerCreationException { // Note this method is thread-safe as a Transaction is only visible to a single thread at time. Key key = new Key(transaction, unitName); EntityManager em = cache.get(key); if (em == null) { // no entity manager for the persistence unit associated with the transaction EntityManagerFactory emf = emfCache.get(unitName); if (emf == null) { throw new EntityManagerCreationException("No EntityManagerFactory found for persistence unit: " + unitName); } em = emf.createEntityManager(); // don't synchronize on the transaction since it can assume to be bound to a thread at this point registerTransactionScopedSync(proxy, key); cache.put(key, em); } return em; } private void registerTransactionScopedSync(HibernateProxy proxy, Key key) throws EntityManagerCreationException { try { TransactionScopedSync sync = new TransactionScopedSync(key, proxy); key.transaction.registerSynchronization(sync); } catch (RollbackException | SystemException e) { throw new EntityManagerCreationException(e); } } /** * Callback used with a transaction-scoped EntityManager to remove it from the cache and close it. */ private class TransactionScopedSync implements Synchronization { private Key key; private HibernateProxy proxy; private TransactionScopedSync(Key key, HibernateProxy proxy) { this.key = key; this.proxy = proxy; } public void beforeCompletion() { } public void afterCompletion(int status) { proxy.clearEntityManager(); EntityManager manager = cache.remove(key); manager.close(); } } private class Key { private Transaction transaction; private String unitName; private Key(Transaction transaction, String unitName) { this.transaction = transaction; this.unitName = unitName; } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Key key = (Key) o; return !(transaction != null ? !transaction.equals(key.transaction) : key.transaction != null) && !(unitName != null ? !unitName.equals( key.unitName) : key.unitName != null); } public int hashCode() { int result = transaction != null ? transaction.hashCode() : 0; result = 31 * result + (unitName != null ? unitName.hashCode() : 0); return result; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy