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

📄 extendedentitymanagercreator.java

📁 Spring API核心源代码 Spring API核心源代码 Spring API核心源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			EntityManager rawEntityManager, EntityManagerPlusOperations plusOperations,
			PersistenceExceptionTranslator exceptionTranslator, Boolean jta, boolean containerManaged) {

		Assert.notNull(rawEntityManager, "EntityManager must not be null");
		Class[] ifcs = ClassUtils.getAllInterfaces(rawEntityManager);
		if (plusOperations != null) {
			ifcs = (Class[]) ObjectUtils.addObjectToArray(ifcs, EntityManagerPlusOperations.class);
		}
		return (EntityManager) Proxy.newProxyInstance(
				ExtendedEntityManagerCreator.class.getClassLoader(), ifcs,
				new ExtendedEntityManagerInvocationHandler(
						rawEntityManager, plusOperations, exceptionTranslator, jta, containerManaged));
	}


	/**
	 * InvocationHandler for extended EntityManagers as defined in the JPA spec.
	 */
	private static class ExtendedEntityManagerInvocationHandler implements InvocationHandler {
		
		private static final Log logger = LogFactory.getLog(ExtendedEntityManagerInvocationHandler.class);

		private final EntityManager target;

		private final EntityManagerPlusOperations plusOperations;

		private final PersistenceExceptionTranslator exceptionTranslator;

		private final boolean containerManaged;

		private boolean jta;

		private ExtendedEntityManagerInvocationHandler(
				EntityManager target, EntityManagerPlusOperations plusOperations,
				PersistenceExceptionTranslator exceptionTranslator, Boolean jta, boolean containerManaged) {

			this.target = target;
			this.plusOperations = plusOperations;
			this.exceptionTranslator = exceptionTranslator;
			this.jta = (jta != null ? jta.booleanValue() : isJtaEntityManager());
			this.containerManaged = containerManaged;
		}

		private boolean isJtaEntityManager() {
			try {
				this.target.getTransaction();
				return false;
			}
			catch (IllegalStateException ex) {
				logger.debug("Cannot access EntityTransaction handle - assuming we're in a JTA environment");
				return true;
			}
		}

		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			// Invocation on EntityManager interface coming in...

			if (method.getDeclaringClass().equals(EntityManagerPlusOperations.class)) {
				return method.invoke(this.plusOperations, args);
			}

			if (method.getName().equals("equals")) {
				// Only consider equal when proxies are identical.
				return (proxy == args[0]);
			}
			else if (method.getName().equals("hashCode")) {
				// Use hashCode of EntityManager proxy.
				return hashCode();
			}
			else if (method.getName().equals("joinTransaction")) {
				doJoinTransaction(true);
				return null;
			}
			else if (method.getName().equals("getTransaction")) {
				if (this.containerManaged) {
					throw new IllegalStateException("Cannot execute getTransaction() on " +
						"a container-managed EntityManager");
				}
			}
			else if (method.getName().equals("close")) {
				if (this.containerManaged) {
					throw new IllegalStateException("Invalid usage: Cannot close a container-managed EntityManager");
				}
			}
			else if (method.getName().equals("isOpen")) {
				if (this.containerManaged) {
					return true;
				}
			}

			// Do automatic joining if required.
			if (this.containerManaged) {
				doJoinTransaction(false);
			}

			// Invoke method on current EntityManager.
			try {
				return method.invoke(this.target, args);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}

		/**
		 * Join an existing transaction, if not already joined.
		 * @param enforce whether to enforce the transaction
		 * (i.e. whether failure to join is considered fatal)
		 */
		private void doJoinTransaction(boolean enforce) {
			if (this.jta) {
				// Let's try whether we're in a JTA transaction.
				try {
					this.target.joinTransaction();
					logger.debug("Joined JTA transaction");
				}
				catch (TransactionRequiredException ex) {
					if (!enforce) {
						logger.debug("No JTA transaction to join: " + ex);
					}
					else {
						throw ex;
					}
				}
			}
			else {
				if (TransactionSynchronizationManager.isSynchronizationActive()) {
					if (!TransactionSynchronizationManager.hasResource(this.target)) {
						enlistInCurrentTransaction();
					}
					logger.debug("Joined local transaction");
				}
				else {
					if (!enforce) {
						logger.debug("No local transaction to join");
					}
					else {
						throw new TransactionRequiredException("No local transaction to join");
					}
				}
			}
		}

		/**
		 * Enlist this application-managed EntityManager in the current transaction.
		 */
		private void enlistInCurrentTransaction() {
			// Resource local transaction, need to acquire the EntityTransaction,
			// start a transaction now and enlist a synchronization for
			// commit or rollback later.
			EntityTransaction et = this.target.getTransaction();
			et.begin();
			if (logger.isDebugEnabled()) {
				logger.debug("Starting resource local transaction on application-managed " +
						"EntityManager [" + this.target + "]");
			}
			EntityManagerHolder emh = new EntityManagerHolder(this.target);
			ExtendedEntityManagerSynchronization extendedEntityManagerSynchronization =
					new ExtendedEntityManagerSynchronization(emh, this.exceptionTranslator);
			TransactionSynchronizationManager.bindResource(this.target,
					extendedEntityManagerSynchronization);
			TransactionSynchronizationManager.registerSynchronization(extendedEntityManagerSynchronization);
		}
	}


	/**
	 * TransactionSynchronization enlisting an extended EntityManager
	 * with a current Spring transaction.
	 */
	private static class ExtendedEntityManagerSynchronization extends TransactionSynchronizationAdapter {

		private final EntityManagerHolder entityManagerHolder;

		private final PersistenceExceptionTranslator exceptionTranslator;

		private boolean holderActive = true;

		public ExtendedEntityManagerSynchronization(
				EntityManagerHolder emHolder, PersistenceExceptionTranslator exceptionTranslator) {

			this.entityManagerHolder = emHolder;
			this.exceptionTranslator = exceptionTranslator;
		}

		public int getOrder() {
			return EntityManagerFactoryUtils.ENTITY_MANAGER_SYNCHRONIZATION_ORDER + 1;
		}

		public void suspend() {
			if (this.holderActive) {
				TransactionSynchronizationManager.unbindResource(this.entityManagerHolder.getEntityManager());
			}
		}

		public void resume() {
			if (this.holderActive) {
				TransactionSynchronizationManager.bindResource(
						this.entityManagerHolder.getEntityManager(), this.entityManagerHolder);
			}
		}

		public void beforeCompletion() {
			TransactionSynchronizationManager.unbindResource(this.entityManagerHolder.getEntityManager());
			this.holderActive = false;
		}

		public void afterCommit() {
			// Trigger commit here to let exceptions propagate to the caller.
			try {
				this.entityManagerHolder.getEntityManager().getTransaction().commit();
			}
			catch (RuntimeException ex) {
				throw convertCompletionException(ex);
			}
		}

		public void afterCompletion(int status) {
			this.entityManagerHolder.setSynchronizedWithTransaction(false);
			if (status != STATUS_COMMITTED) {
				// Haven't had an afterCommit call: trigger a rollback.
				try {
					this.entityManagerHolder.getEntityManager().getTransaction().rollback();
				}
				catch (RuntimeException ex) {
					throw convertCompletionException(ex);
				}
			}
			// Don't close the EntityManager... That's up to the user.
		}

		private RuntimeException convertCompletionException(RuntimeException ex) {
			DataAccessException daex = (this.exceptionTranslator != null) ?
					this.exceptionTranslator.translateExceptionIfPossible(ex) :
					EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);
			return (daex != null ? daex : ex);
		}
	}

}

⌨️ 快捷键说明

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