org.springframework.integration.jpa.core.DefaultJpaOperations.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.integration.jpa.core.DefaultJpaOperations.java

Source

/*
 * Copyright 2002-2016 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.integration.jpa.core;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.persistence.Parameter;
import javax.persistence.Query;

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

import org.springframework.integration.jpa.support.JpaUtils;
import org.springframework.integration.jpa.support.parametersource.ParameterSource;
import org.springframework.integration.jpa.support.parametersource.PositionSupportingParameterSource;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * Class similar to JPA template limited to the operations required for the JPA adapters/gateway
 * not using JpaTemplate as the class is deprecated since Spring 3.1
 *
 * @author Amol Nayak
 * @author Gunnar Hillert
 * @author Artem Bilan
 *
 * @since 2.2
 */
public class DefaultJpaOperations extends AbstractJpaOperations {

    private static final Log logger = LogFactory.getLog(DefaultJpaOperations.class);

    @Override
    public void delete(Object entity) {
        Assert.notNull(entity, "The entity must not be null!");
        entityManager.remove(entity);
    }

    @Override
    public void deleteInBatch(Iterable<?> entities) {

        Assert.notNull(entities, "entities must not be null.");

        Iterator<?> iterator = entities.iterator();

        if (!iterator.hasNext()) {
            return;
        }

        Class<?> entityClass = null;

        for (Object object : entities) {
            if (entityClass == null) {
                entityClass = object.getClass();
            } else {
                if (entityClass != object.getClass()) {
                    throw new IllegalArgumentException("entities must be of the same type.");
                }
            }
        }

        final String entityName = JpaUtils.getEntityName(entityManager, entityClass);
        final String queryString = JpaUtils.getQueryString(JpaUtils.DELETE_ALL_QUERY_STRING, entityName);

        JpaUtils.applyAndBind(queryString, entities, entityManager).executeUpdate();

    }

    @Override
    public int executeUpdate(String updateQuery, ParameterSource source) {
        Query query = entityManager.createQuery(updateQuery);
        setParametersIfRequired(updateQuery, source, query);
        return query.executeUpdate();
    }

    @Override
    public int executeUpdateWithNamedQuery(String updateQuery, ParameterSource source) {
        Query query = entityManager.createNamedQuery(updateQuery);
        setParametersIfRequired(updateQuery, source, query);
        return query.executeUpdate();
    }

    @Override
    public int executeUpdateWithNativeQuery(String updateQuery, ParameterSource source) {
        Query query = entityManager.createNativeQuery(updateQuery);
        setParametersIfRequired(updateQuery, source, query);
        return query.executeUpdate();
    }

    @Override
    public <T> T find(Class<T> entityType, Object id) {
        return entityManager.find(entityType, id);
    }

    private Query getQuery(String queryString, ParameterSource source) {
        Query query = entityManager.createQuery(queryString);
        setParametersIfRequired(queryString, source, query);
        return query;
    }

    @Override
    public List<?> getResultListForClass(Class<?> entityClass, int firstResult, int maxNumberOfResults) {

        final String entityName = JpaUtils.getEntityName(entityManager, entityClass);
        final Query query = entityManager.createQuery("select x from " + entityName + " x", entityClass);
        if (firstResult > 0) {
            query.setFirstResult(firstResult);
        }
        if (maxNumberOfResults > 0) {
            query.setMaxResults(maxNumberOfResults);
        }

        return query.getResultList();

    }

    @Override
    public List<?> getResultListForNamedQuery(String selectNamedQuery, ParameterSource parameterSource,
            int firstResult, int maxNumberOfResults) {

        final Query query = entityManager.createNamedQuery(selectNamedQuery);
        setParametersIfRequired(selectNamedQuery, parameterSource, query);

        if (firstResult > 0) {
            query.setFirstResult(firstResult);
        }
        if (maxNumberOfResults > 0) {
            query.setMaxResults(maxNumberOfResults);
        }

        return query.getResultList();

    }

    @Override
    public List<?> getResultListForNativeQuery(String selectQuery, Class<?> entityClass,
            ParameterSource parameterSource, int firstResult, int maxNumberOfResults) {

        final Query query;

        if (entityClass == null) {
            query = entityManager.createNativeQuery(selectQuery);
        } else {
            query = entityManager.createNativeQuery(selectQuery, entityClass);
        }

        setParametersIfRequired(selectQuery, parameterSource, query);

        if (firstResult > 0) {
            query.setFirstResult(firstResult);
        }
        if (maxNumberOfResults > 0) {
            query.setMaxResults(maxNumberOfResults);
        }

        return query.getResultList();
    }

    @Override
    public List<?> getResultListForQuery(String query, ParameterSource source) {
        return getResultListForQuery(query, source, 0, 0);
    }

    @Override
    public List<?> getResultListForQuery(String queryString, ParameterSource source, int firstResult,
            int maxNumberOfResults) {

        Query query = getQuery(queryString, source);

        if (firstResult > 0) {
            query.setFirstResult(firstResult);
        }
        if (maxNumberOfResults > 0) {
            query.setMaxResults(maxNumberOfResults);
        }

        return query.getResultList();
    }

    @Override
    public Object getSingleResultForQuery(String queryString, ParameterSource source) {
        Query query = getQuery(queryString, source);
        return query.getSingleResult();
    }

    @Override
    public Object merge(Object entity) {
        return this.merge(entity, 0, false);
    }

    @Override
    public Object merge(Object entity, int flushSize, boolean clearOnFlush) {
        Assert.notNull(entity, "The object to merge must not be null.");
        return this.persistOrMerge(entity, true, flushSize, clearOnFlush);
    }

    @Override
    public void persist(Object entity) {
        this.persist(entity, 0, false);
    }

    @Override
    public void persist(Object entity, int flushSize, boolean clearOnFlush) {
        Assert.notNull(entity, "The object to persist must not be null.");
        persistOrMerge(entity, false, flushSize, clearOnFlush);
    }

    private Object persistOrMerge(Object entity, boolean isMerge, int flushSize, boolean clearOnFlush) {
        Object result = null;

        if (entity instanceof Iterable) {

            @SuppressWarnings("unchecked")
            Iterable<Object> entities = (Iterable<Object>) entity;

            int savedEntities = 0;
            int nullEntities = 0;

            List<Object> mergedEntities = new ArrayList<Object>();

            for (Object iteratedEntity : entities) {
                if (iteratedEntity == null) {
                    nullEntities++;
                } else {
                    if (isMerge) {
                        mergedEntities.add(entityManager.merge(iteratedEntity));
                    } else {
                        entityManager.persist(iteratedEntity);
                    }
                    savedEntities++;
                    if (flushSize > 0 && savedEntities % flushSize == 0) {
                        entityManager.flush();
                        if (clearOnFlush) {
                            entityManager.clear();
                        }
                    }
                }
            }

            if (logger.isDebugEnabled()) {
                logger.debug(String.format("%s %s entities. %s NULL entities were ignored.",
                        isMerge ? "Merged" : "Persisted", savedEntities, nullEntities));
            }

            if (isMerge) {
                result = mergedEntities;
            }
        } else {
            if (isMerge) {
                result = entityManager.merge(entity);
            } else {
                entityManager.persist(entity);
            }
        }

        if (flushSize > 0) {
            entityManager.flush();
            if (clearOnFlush) {
                entityManager.clear();
            }
        }

        return result;
    }

    /**
     * Given a JPQL query, this method gets all parameters defined in this query and
     * use the {@link ParameterSource} to find their values and set them.
     *
     */
    private void setParametersIfRequired(String queryString, ParameterSource source, Query query) {
        Set<Parameter<?>> parameters = query.getParameters();

        if (parameters != null && !parameters.isEmpty()) {
            if (source != null) {
                for (Parameter<?> param : parameters) {
                    String paramName = param.getName();
                    Integer position = param.getPosition();

                    final Object paramValue;

                    if (position != null) {

                        if (source instanceof PositionSupportingParameterSource) {
                            paramValue = ((PositionSupportingParameterSource) source).getValueByPosition(position);
                            query.setParameter(position, paramValue);
                        } else {
                            throw new JpaOperationFailedException("Positional Parameters are only support "
                                    + "for PositionSupportingParameterSources.", queryString);
                        }

                    } else {

                        if (StringUtils.hasText(paramName)) {
                            paramValue = source.getValue(paramName);
                            query.setParameter(paramName, paramValue);
                        } else {
                            throw new JpaOperationFailedException(
                                    "This parameter does not contain a parameter name. "
                                            + "Additionally it is not a positional parameter, neither.",
                                    queryString);
                        }
                    }

                }
            } else {
                throw new IllegalArgumentException("Query has parameters but no parameter source provided");
            }

        }
    }

}