⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extendedentitymanagercreator.java

📁 Spring API核心源代码 Spring API核心源代码 Spring API核心源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright 2002-2007 the original author or authors.
 *
 * 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 org.springframework.orm.jpa;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.TransactionRequiredException;
import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

/**
 * Factory for dynamic EntityManager proxies that follow the JPA spec's
 * semantics for "extended" EntityManagers.
 *
 * <p>Supports explicit joining of a transaction through the
 * <code>joinTransaction()</code> method ("application-managed extended
 * EntityManager") as well as automatic joining on each operation
 * ("container-managed extended EntityManager").
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @since 2.0
 */
public abstract class ExtendedEntityManagerCreator {

	/**
	 * Create an EntityManager that can join transactions with the
	 * <code>joinTransaction()</code> method, but is not automatically
	 * managed by the container.
	 * @param rawEntityManager raw EntityManager
	 * @param plusOperations an implementation of the EntityManagerPlusOperations
	 * interface, if those operations should be exposed (may be <code>null</code>)
	 * @return an application-managed EntityManager that can join transactions
	 * but does not participate in them automatically
	 */
	public static EntityManager createApplicationManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations) {

		return createProxy(rawEntityManager, plusOperations, null, null, false);
	}

	/**
	 * Create an EntityManager that can join transactions with the
	 * <code>joinTransaction()</code> method, but is not automatically
	 * managed by the container.
	 * @param rawEntityManager raw EntityManager
	 * @param plusOperations an implementation of the EntityManagerPlusOperations
	 * interface, if those operations should be exposed (may be <code>null</code>)
	 * @param exceptionTranslator the exception translator to use for translating
	 * JPA commit/rollback exceptions during transaction synchronization
	 * (may be <code>null</code>)
	 * @return an application-managed EntityManager that can join transactions
	 * but does not participate in them automatically
	 */
	public static EntityManager createApplicationManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations,
			PersistenceExceptionTranslator exceptionTranslator) {

		return createProxy(rawEntityManager, plusOperations, exceptionTranslator, null, false);
	}

	/**
	 * Create an EntityManager that can join transactions with the
	 * <code>joinTransaction()</code> method, but is not automatically
	 * managed by the container.
	 * @param rawEntityManager raw EntityManager
	 * @param emfInfo the EntityManagerFactoryInfo to obtain the
	 * EntityManagerPlusOperations and PersistenceUnitInfo from
	 * @return an application-managed EntityManager that can join transactions
	 * but does not participate in them automatically
	 */
	public static EntityManager createApplicationManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerFactoryInfo emfInfo) {

		return createProxy(rawEntityManager, emfInfo, false);
	}


	/**
	 * Create an EntityManager that automatically joins transactions on each
	 * operation in a transaction.
	 * @param rawEntityManager raw EntityManager
	 * @param plusOperations an implementation of the EntityManagerPlusOperations
	 * interface, if those operations should be exposed (may be <code>null</code>)
	 * @return a container-managed EntityManager that will automatically participate
	 * in any managed transaction
	 */
	public static EntityManager createContainerManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations) {

		return createProxy(rawEntityManager, plusOperations, null, null, true);
	}

	/**
	 * Create an EntityManager that automatically joins transactions on each
	 * operation in a transaction.
	 * @param rawEntityManager raw EntityManager
	 * @param plusOperations an implementation of the EntityManagerPlusOperations
	 * interface, if those operations should be exposed (may be <code>null</code>)
	 * @param exceptionTranslator the exception translator to use for translating
	 * JPA commit/rollback exceptions during transaction synchronization
	 * (may be <code>null</code>)
	 * @return a container-managed EntityManager that will automatically participate
	 * in any managed transaction
	 */
	public static EntityManager createContainerManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations,
			PersistenceExceptionTranslator exceptionTranslator) {

		return createProxy(rawEntityManager, plusOperations, exceptionTranslator, null, true);
	}

	/**
	 * Create an EntityManager that automatically joins transactions on each
	 * operation in a transaction.
	 * @param rawEntityManager raw EntityManager
	 * @param emfInfo the EntityManagerFactoryInfo to obtain the
	 * EntityManagerPlusOperations and PersistenceUnitInfo from
	 * @return a container-managed EntityManager that will automatically participate
	 * in any managed transaction
	 */
	public static EntityManager createContainerManagedEntityManager(
			EntityManager rawEntityManager, EntityManagerFactoryInfo emfInfo) {

		return createProxy(rawEntityManager, emfInfo, true);
	}


	/**
	 * Create an EntityManager that automatically joins transactions on each
	 * operation in a transaction.
	 * @param emf the EntityManagerFactory to create the EntityManager with.
	 * If this implements the EntityManagerFactoryInfo interface, appropriate handling
	 * of the native EntityManagerFactory and available EntityManagerPlusOperations
	 * will automatically apply.
	 * @return a container-managed EntityManager that will automatically participate
	 * in any managed transaction
	 * @see javax.persistence.EntityManagerFactory#createEntityManager()
	 */
	public static EntityManager createContainerManagedEntityManager(EntityManagerFactory emf) {
		return createContainerManagedEntityManager(emf, null);
	}

	/**
	 * Create an EntityManager that automatically joins transactions on each
	 * operation in a transaction.
	 * @param emf the EntityManagerFactory to create the EntityManager with.
	 * If this implements the EntityManagerFactoryInfo interface, appropriate handling
	 * of the native EntityManagerFactory and available EntityManagerPlusOperations
	 * will automatically apply.
	 * @param properties the properties to be passed into the <code>createEntityManager</code>
	 * call (may be <code>null</code>)
	 * @return a container-managed EntityManager that will automatically participate
	 * in any managed transaction
	 * @see javax.persistence.EntityManagerFactory#createEntityManager(java.util.Map)
	 */
	public static EntityManager createContainerManagedEntityManager(EntityManagerFactory emf, Map properties) {
		Assert.notNull(emf, "EntityManagerFactory must not be null");
		if (emf instanceof EntityManagerFactoryInfo) {
			EntityManagerFactoryInfo emfInfo = (EntityManagerFactoryInfo) emf;
			EntityManagerFactory nativeEmf = emfInfo.getNativeEntityManagerFactory();
			EntityManager rawEntityManager = (!CollectionUtils.isEmpty(properties) ?
					nativeEmf.createEntityManager(properties) : nativeEmf.createEntityManager());
			return createProxy(rawEntityManager, emfInfo, true);
		}
		else {
			EntityManager rawEntityManager = (!CollectionUtils.isEmpty(properties) ?
					emf.createEntityManager(properties) : emf.createEntityManager());
			return createProxy(rawEntityManager, null, null, null, true);
		}
	}


	/**
	 * Actually create the EntityManager proxy.
	 * @param rawEntityManager raw EntityManager
	 * @param emfInfo the EntityManagerFactoryInfo to obtain the
	 * EntityManagerPlusOperations and PersistenceUnitInfo from
	 * @param containerManaged whether to follow container-managed EntityManager
	 * or application-managed EntityManager semantics
	 * @return the EntityManager proxy
	 */
	private static EntityManager createProxy(
			EntityManager rawEntityManager, EntityManagerFactoryInfo emfInfo, boolean containerManaged) {

		Assert.notNull(emfInfo, "EntityManagerFactoryInfo must not be null");
		JpaDialect jpaDialect = emfInfo.getJpaDialect();
		EntityManagerPlusOperations plusOperations = null;
		if (jpaDialect != null && jpaDialect.supportsEntityManagerPlusOperations()) {
			plusOperations = jpaDialect.getEntityManagerPlusOperations(rawEntityManager);
		}
		PersistenceUnitInfo pui = emfInfo.getPersistenceUnitInfo();
		Boolean jta = (pui != null ? pui.getTransactionType() == PersistenceUnitTransactionType.JTA : null);
		return createProxy(rawEntityManager, plusOperations, jpaDialect, jta, containerManaged);
	}

	/**
	 * Actually create the EntityManager proxy.
	 * @param rawEntityManager raw EntityManager
	 * @param plusOperations an implementation of the EntityManagerPlusOperations
	 * interface, if those operations should be exposed (may be <code>null</code>)
	 * @param exceptionTranslator the PersistenceException translator to use
	 * @param jta whether to create a JTA-aware EntityManager
	 * (or <code>null</code> if not known in advance)
	 * @param containerManaged whether to follow container-managed EntityManager
	 * or application-managed EntityManager semantics
	 * @return the EntityManager proxy
	 */
	private static EntityManager createProxy(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -