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

org.jbpm.persistence.JpaProcessPersistenceContext Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017 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.jbpm.persistence;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.drools.persistence.api.TransactionManager;
import org.drools.persistence.api.TransactionManagerHelper;
import org.drools.persistence.jpa.JpaPersistenceContext;
import org.jbpm.persistence.api.PersistentCorrelationKey;
import org.jbpm.persistence.api.PersistentProcessInstance;
import org.jbpm.persistence.api.ProcessPersistenceContext;
import org.jbpm.persistence.correlation.CorrelationKeyInfo;
import org.jbpm.persistence.processinstance.JPASignalManager;
import org.jbpm.persistence.processinstance.ProcessInstanceInfo;
import org.jbpm.process.instance.ProcessInstance;
import org.jbpm.process.instance.ProcessInstanceManager;
import org.kie.internal.process.CorrelationKey;

public class JpaProcessPersistenceContext extends JpaPersistenceContext
    implements
    ProcessPersistenceContext {
    
    public JpaProcessPersistenceContext(EntityManager em, TransactionManager txm) {
        super( em, txm );
    }

    public JpaProcessPersistenceContext(EntityManager em, boolean useJTA, boolean locking, String lockingMode, TransactionManager txm) {
        super( em, useJTA, locking, lockingMode, txm);
    }

    public PersistentProcessInstance persist(PersistentProcessInstance processInstanceInfo) {
        EntityManager em = getEntityManager();
        em.persist(processInstanceInfo);
        TransactionManagerHelper.addToUpdatableSet(txm, processInstanceInfo);
        if( this.pessimisticLocking ) { 
        	em.flush();
            return em.find(ProcessInstanceInfo.class, processInstanceInfo.getId(), lockMode );
        }
        return processInstanceInfo;
    }

    public PersistentProcessInstance findProcessInstanceInfo(Long processId) {
    	EntityManager em = getEntityManager();       
    	if( this.pessimisticLocking ) { 
            return em.find( ProcessInstanceInfo.class, processId, lockMode );
        }
        return em.find( ProcessInstanceInfo.class, processId );
    }

    public void remove(PersistentProcessInstance processInstanceInfo) {
        getEntityManager().remove( processInstanceInfo );
        TransactionManagerHelper.removeFromUpdatableSet(txm, processInstanceInfo);
        List correlations = getEntityManager().createNamedQuery("GetCorrelationKeysByProcessInstanceId")
        .setParameter("pId", processInstanceInfo.getId()).getResultList();
        if (correlations != null) {
            for (CorrelationKeyInfo key : correlations) {
                getEntityManager().remove(key);
            }
        }
    }

    @Override
    public void evict(PersistentProcessInstance processInstanceInfo) {
        getEntityManager().detach(processInstanceInfo);
    }

    /**
     * This method is used by the {@link JPASignalManager} in order to load {@link ProcessInstance} instances
     * into the {@link ProcessInstanceManager} cache so that they can then be signalled. 
     * 

* Unfortunately, with regards to locking, the method is not always called during a transaction, which means * that including logic to lock the query will cause exceptions and is not feasible. *

* Because the {@link org.drools.core.command.SingleSessionCommandService} design is based around a synchronized execute(...) method, * it's not possible for one thread to create a process instance while another thread simultaneously tries to * signal it. That means that a * phantom read * race condition, that might be caused by a lack of pessimistic locking on this query, isn't possible. *

* Of course, if you're using multiple ksessions to simultaneoulsy interact with the same process instance, * all bets are off. This however is true for almost everything involving process instances, so that it's not * worth discussing. *

*/ public List getProcessInstancesWaitingForEvent(String type) { EntityManager entityManager = getEntityManager(); if (entityManager != null) { Query processInstancesForEvent = getEntityManager().createNamedQuery( "ProcessInstancesWaitingForEvent" ); processInstancesForEvent.setParameter( "type", type ); return (List) processInstancesForEvent.getResultList(); } else { // entity manager can be null when fireActivationCreated is // called on session unmarshalling return new ArrayList(); } } public PersistentCorrelationKey persist(PersistentCorrelationKey correlationKeyInfo) { try { EntityManager em = getEntityManager(); em.persist(correlationKeyInfo); em.flush(); if (this.pessimisticLocking) { return em.find(CorrelationKeyInfo.class, correlationKeyInfo.getId(), this.lockMode); } return correlationKeyInfo; } catch (PersistenceException e) { throw new RuntimeException(correlationKeyInfo + " failed to persist", e); } } /** * With regards to locking, the method is not always called during a transaction, which means * that including logic to lock the query will cause exceptions and is not feasible. *

* However, this is not an issue: see the {@link #getProcessInstancesWaitingForEvent(String)} documentation * for more information. The same logic applies to this method. *

*/ public Long getProcessInstanceByCorrelationKey(CorrelationKey correlationKey) { Query processInstancesForEvent = getEntityManager().createNamedQuery( "GetProcessInstanceIdByCorrelation" ); processInstancesForEvent.setParameter( "ckey", correlationKey.toExternalForm()); try { return (Long) processInstancesForEvent.getSingleResult(); } catch (NonUniqueResultException e) { return null; } catch (NoResultException e) { return null; } } @Override public List findAllProcessInstanceInfo() { EntityManager em = getEntityManager(); return em.createQuery("SELECT o.id FROM ProcessInstanceInfo o", Long.class).getResultList(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy