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

org.apache.camel.component.jpa.JpaHelper Maven / Gradle / Ivy

There is a newer version: 4.9.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.camel.component.jpa;

import java.util.HashMap;
import java.util.Map;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;

import org.apache.camel.Exchange;
import org.springframework.orm.jpa.SharedEntityManagerCreator;

/**
 * Helper for JPA.
 */
public final class JpaHelper {

    private JpaHelper() {
    }

    /**
     * Gets or creates an {@link jakarta.persistence.EntityManager} to use.
     *
     * @param  exchange                 the current exchange, or null if no exchange
     * @param  entityManagerFactory     the entity manager factory (mandatory)
     * @param  usePassedInEntityManager whether to use an existing {@link jakarta.persistence.EntityManager} which has
     *                                  been stored on the exchange in the header with key
     *                                  {@link org.apache.camel.component.jpa.JpaConstants#ENTITY_MANAGER}
     * @param  useSharedEntityManager   whether to use SharedEntityManagerCreator if not already passed in
     * @return                          the entity manager (is never null)
     */
    public static EntityManager getTargetEntityManager(
            Exchange exchange, EntityManagerFactory entityManagerFactory,
            boolean usePassedInEntityManager, boolean useSharedEntityManager, boolean allowRecreate) {
        EntityManager em = null;

        // favor using entity manager provided as a header from the end user
        if (exchange != null && usePassedInEntityManager) {
            em = exchange.getIn().getHeader(JpaConstants.ENTITY_MANAGER, EntityManager.class);
        }

        // then try reuse any entity manager which has been previously created and stored on the exchange
        if (em == null && exchange != null) {
            em = getEntityManagerMap(exchange).get(getKey(entityManagerFactory));
        }

        // then try reuse any entity manager from the transaction context
        if (em == null && exchange != null && exchange.isTransacted()) {
            Map data = getTransactionContextData(exchange);
            if (data != null) {
                em = (EntityManager) data.get(getKey(entityManagerFactory));
            }
        }

        if (em == null && useSharedEntityManager) {
            em = SharedEntityManagerCreator.createSharedEntityManager(entityManagerFactory);
        }

        if (em == null) {
            em = createEntityManager(exchange, entityManagerFactory);
        }

        if (allowRecreate && em == null || !em.isOpen()) {
            em = createEntityManager(exchange, entityManagerFactory);
        }

        return em;
    }

    /**
     * Copy JpaConstants.ENTITY_MANAGER property from source to target exchange.
     *
     * @param target The target exchange
     * @param source The source exchange
     */
    public static void copyEntityManagers(Exchange target, Exchange source) {
        if (target != null && source != null && target.getProperty(JpaConstants.ENTITY_MANAGER) == null) {
            Map entityManagers = source.getProperty(JpaConstants.ENTITY_MANAGER, Map.class);
            if (entityManagers != null) {
                target.setProperty(JpaConstants.ENTITY_MANAGER, entityManagers);
            }
        }
    }

    private static EntityManager createEntityManager(Exchange exchange, EntityManagerFactory entityManagerFactory) {
        EntityManager em;
        em = entityManagerFactory.createEntityManager();
        if (exchange != null) {
            // we want to reuse the EM so store as property and make sure we close it when done with the exchange
            Map entityManagers = getEntityManagerMap(exchange);
            entityManagers.put(getKey(entityManagerFactory), em);

            // we want to reuse the EM in the same transaction
            if (exchange.isTransacted()) {
                Map data = getTransactionContextData(exchange);
                if (data != null) {
                    data.put(getKey(entityManagerFactory), em);
                }
            }
            exchange.getExchangeExtension().addOnCompletion(new JpaCloseEntityManagerOnCompletion(em));
        }
        return em;
    }

    private static Map getTransactionContextData(Exchange exchange) {
        Map data = null;
        if (exchange.isTransacted()) {
            data = exchange.getProperty(Exchange.TRANSACTION_CONTEXT_DATA, Map.class);
        }
        return data;
    }

    @SuppressWarnings("unchecked")
    private static Map getEntityManagerMap(Exchange exchange) {
        Map entityManagers = exchange.getProperty(JpaConstants.ENTITY_MANAGER, Map.class);
        if (entityManagers == null) {
            entityManagers = new HashMap<>();
            exchange.setProperty(JpaConstants.ENTITY_MANAGER, entityManagers);
        }
        return entityManagers;
    }

    private static String getKey(EntityManagerFactory entityManagerFactory) {
        return String.valueOf(entityManagerFactory.hashCode());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy