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

org.drools.persistence.jpa.AbstractPersistenceContextManager Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
/*
 * Copyright 2011 Red Hat, Inc. and/or its affiliates.
 *
 * 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.drools.persistence.jpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.drools.persistence.TransactionManager;
import org.kie.api.runtime.Environment;
import org.kie.api.runtime.EnvironmentName;
import org.kie.api.runtime.KieSession;

/**
 * This class manages {@link JpaPersistenceContext} objects, and the underlying persistence context ({@link EntityManager}) 
 * instances for a persistent {@link KieSession} and other infrastructure classes that use persistence in KIE projects.
 * 

* (For reference in the following documentation: the {@link EntityManager} is the class used to represent a persistence context) *

* There are 2 issues to take into account when looking at or modifying the code here:
    *
  1. One of the features made available here is the ability for the user to supply their own (Command Scoped) persistence * context for use by the {@link KieSession}
  2. *
  3. However, significant race-conditions arise when a Command Scoped persistence context is used in one persistent * {@link KieSession} by multiple threads. In other words, when multiple threads call operations on a Singleton persistent * {@link KieSession}.
  4. *
* * This class uses {@link ThreadLocal} instances for two things:
    *
  1. The internal Command Scoped {@link EntityManager} instance.
  2. *
  3. *
*/ public abstract class AbstractPersistenceContextManager { protected final Environment env; protected final EntityManagerFactory emf; protected final TransactionManager txm; protected volatile EntityManager appScopedEntityManager; protected volatile EntityManager cmdScopedEntityManager; protected volatile boolean internalAppScopedEntityManagerFlag; protected volatile boolean internalCmdScopedEntityManagerFlag; public AbstractPersistenceContextManager(Environment env) { this.env = env; this.emf = ( EntityManagerFactory ) env.get( EnvironmentName.ENTITY_MANAGER_FACTORY ); this.txm = ( TransactionManager ) env.get(EnvironmentName.TRANSACTION_MANAGER); } public EntityManager getApplicationScopedEntityManager() { if ( this.appScopedEntityManager == null ) { // Use the App scoped EntityManager if the user has provided it, and it is open. this.appScopedEntityManager = (EntityManager) this.env.get( EnvironmentName.APP_SCOPED_ENTITY_MANAGER ); if ( this.appScopedEntityManager != null && !this.appScopedEntityManager.isOpen() ) { throw new RuntimeException("Provided APP_SCOPED_ENTITY_MANAGER is not open"); } if ( this.appScopedEntityManager == null ) { internalAppScopedEntityManagerFlag = true; this.appScopedEntityManager = this.emf.createEntityManager(); this.env.set( EnvironmentName.APP_SCOPED_ENTITY_MANAGER, this.appScopedEntityManager ); if (txm.getStatus() == TransactionManager.STATUS_ACTIVE) { this.txm.putResource(EnvironmentName.APP_SCOPED_ENTITY_MANAGER, this.appScopedEntityManager ); } } else { internalAppScopedEntityManagerFlag = false; } } return appScopedEntityManager; } public EntityManager getCommandScopedEntityManager() { // first check if there is already cmd scoped entity manager as transactional resource EntityManager cmdScopedEntityManager = getInternalCommandScopedEntityManager(); if ( cmdScopedEntityManager == null) { cmdScopedEntityManager = (EntityManager) env.get( EnvironmentName.CMD_SCOPED_ENTITY_MANAGER ); if (cmdScopedEntityManager != null) { this.txm.putResource(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, cmdScopedEntityManager ); } if ( cmdScopedEntityManager == null) { internalCmdScopedEntityManagerFlag = true; cmdScopedEntityManager = this.emf.createEntityManager(); // no need to call joinTransaction as it will do so if one already exists this.env.set( EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, cmdScopedEntityManager ); this.txm.putResource(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, cmdScopedEntityManager ); } else { internalCmdScopedEntityManagerFlag = false; } } cmdScopedEntityManager.joinTransaction(); if (this.appScopedEntityManager != null) { this.appScopedEntityManager.joinTransaction(); } return cmdScopedEntityManager; } public void endCommandScopedEntityManager() { EntityManager cmdScopedEntityManager = getInternalCommandScopedEntityManager(); if ( this.internalCmdScopedEntityManagerFlag ) { if (cmdScopedEntityManager != null && cmdScopedEntityManager.isOpen()) { cmdScopedEntityManager.clear(); } this.env.set( EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, null ); } } public void dispose() { if ( this.internalAppScopedEntityManagerFlag ) { if ( this.appScopedEntityManager != null && this.appScopedEntityManager.isOpen() ) { this.appScopedEntityManager.close(); } this.internalAppScopedEntityManagerFlag = false; this.env.set( EnvironmentName.APP_SCOPED_ENTITY_MANAGER, null ); this.appScopedEntityManager = null; } if ( this.internalCmdScopedEntityManagerFlag ) { EntityManager cmdScopedEntityManager = getInternalCommandScopedEntityManager(); if ( cmdScopedEntityManager != null && cmdScopedEntityManager.isOpen() ) { cmdScopedEntityManager.close(); } this.env.set( EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, null ); this.txm.putResource(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, null ); this.internalCmdScopedEntityManagerFlag = false; } } protected EntityManager getInternalCommandScopedEntityManager() { return (EntityManager) txm.getResource(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy