/*
 * Copyright 2002-2020 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
 *
 *      https://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.dao.support;

import java.util.Collection;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.TypeMismatchDataAccessException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.NumberUtils;

Miscellaneous utility methods for DAO implementations. Useful with any data access technology.
Author:Juergen Hoeller
Since:1.0.2
/** * Miscellaneous utility methods for DAO implementations. * Useful with any data access technology. * * @author Juergen Hoeller * @since 1.0.2 */
public abstract class DataAccessUtils {
Return a single result object from the given Collection.

Returns null if 0 result objects found; throws an exception if more than 1 element found.

Params:
  • results – the result Collection (can be null)
Throws:
Returns:the single result object, or null if none
/** * Return a single result object from the given Collection. * <p>Returns {@code null} if 0 result objects found; * throws an exception if more than 1 element found. * @param results the result Collection (can be {@code null}) * @return the single result object, or {@code null} if none * @throws IncorrectResultSizeDataAccessException if more than one * element has been found in the given Collection */
@Nullable public static <T> T singleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { return null; } if (results.size() > 1) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } return results.iterator().next(); }
Return a single result object from the given Collection.

Throws an exception if 0 or more than 1 element found.

Params:
  • results – the result Collection (can be null but is not expected to contain null elements)
Throws:
Returns:the single result object
/** * Return a single result object from the given Collection. * <p>Throws an exception if 0 or more than 1 element found. * @param results the result Collection (can be {@code null} * but is not expected to contain {@code null} elements) * @return the single result object * @throws IncorrectResultSizeDataAccessException if more than one * element has been found in the given Collection * @throws EmptyResultDataAccessException if no element at all * has been found in the given Collection */
public static <T> T requiredSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { throw new EmptyResultDataAccessException(1); } if (results.size() > 1) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } return results.iterator().next(); }
Return a single result object from the given Collection.

Throws an exception if 0 or more than 1 element found.

Params:
  • results – the result Collection (can be null and is also expected to contain null elements)
Throws:
Returns:the single result object
Since:5.0.2
/** * Return a single result object from the given Collection. * <p>Throws an exception if 0 or more than 1 element found. * @param results the result Collection (can be {@code null} * and is also expected to contain {@code null} elements) * @return the single result object * @throws IncorrectResultSizeDataAccessException if more than one * element has been found in the given Collection * @throws EmptyResultDataAccessException if no element at all * has been found in the given Collection * @since 5.0.2 */
@Nullable public static <T> T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { // This is identical to the requiredSingleResult implementation but differs in the // semantics of the incoming Collection (which we currently can't formally express) if (CollectionUtils.isEmpty(results)) { throw new EmptyResultDataAccessException(1); } if (results.size() > 1) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } return results.iterator().next(); }
Return a unique result object from the given Collection.

Returns null if 0 result objects found; throws an exception if more than 1 instance found.

Params:
  • results – the result Collection (can be null)
Throws:
See Also:
Returns:the unique result object, or null if none
/** * Return a unique result object from the given Collection. * <p>Returns {@code null} if 0 result objects found; * throws an exception if more than 1 instance found. * @param results the result Collection (can be {@code null}) * @return the unique result object, or {@code null} if none * @throws IncorrectResultSizeDataAccessException if more than one * result object has been found in the given Collection * @see org.springframework.util.CollectionUtils#hasUniqueObject */
@Nullable public static <T> T uniqueResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { return null; } if (!CollectionUtils.hasUniqueObject(results)) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } return results.iterator().next(); }
Return a unique result object from the given Collection.

Throws an exception if 0 or more than 1 instance found.

Params:
  • results – the result Collection (can be null but is not expected to contain null elements)
Throws:
See Also:
Returns:the unique result object
/** * Return a unique result object from the given Collection. * <p>Throws an exception if 0 or more than 1 instance found. * @param results the result Collection (can be {@code null} * but is not expected to contain {@code null} elements) * @return the unique result object * @throws IncorrectResultSizeDataAccessException if more than one * result object has been found in the given Collection * @throws EmptyResultDataAccessException if no result object at all * has been found in the given Collection * @see org.springframework.util.CollectionUtils#hasUniqueObject */
public static <T> T requiredUniqueResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { throw new EmptyResultDataAccessException(1); } if (!CollectionUtils.hasUniqueObject(results)) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } return results.iterator().next(); }
Return a unique result object from the given Collection. Throws an exception if 0 or more than 1 result objects found, of if the unique result object is not convertible to the specified required type.
Params:
  • results – the result Collection (can be null but is not expected to contain null elements)
Throws:
Returns:the unique result object
/** * Return a unique result object from the given Collection. * Throws an exception if 0 or more than 1 result objects found, * of if the unique result object is not convertible to the * specified required type. * @param results the result Collection (can be {@code null} * but is not expected to contain {@code null} elements) * @return the unique result object * @throws IncorrectResultSizeDataAccessException if more than one * result object has been found in the given Collection * @throws EmptyResultDataAccessException if no result object * at all has been found in the given Collection * @throws TypeMismatchDataAccessException if the unique object does * not match the specified required type */
@SuppressWarnings("unchecked") public static <T> T objectResult(@Nullable Collection<?> results, @Nullable Class<T> requiredType) throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException { Object result = requiredUniqueResult(results); if (requiredType != null && !requiredType.isInstance(result)) { if (String.class == requiredType) { result = result.toString(); } else if (Number.class.isAssignableFrom(requiredType) && result instanceof Number) { try { result = NumberUtils.convertNumberToTargetClass(((Number) result), (Class<? extends Number>) requiredType); } catch (IllegalArgumentException ex) { throw new TypeMismatchDataAccessException(ex.getMessage()); } } else { throw new TypeMismatchDataAccessException( "Result object is of type [" + result.getClass().getName() + "] and could not be converted to required type [" + requiredType.getName() + "]"); } } return (T) result; }
Return a unique int result from the given Collection. Throws an exception if 0 or more than 1 result objects found, of if the unique result object is not convertible to an int.
Params:
  • results – the result Collection (can be null but is not expected to contain null elements)
Throws:
Returns:the unique int result
/** * Return a unique int result from the given Collection. * Throws an exception if 0 or more than 1 result objects found, * of if the unique result object is not convertible to an int. * @param results the result Collection (can be {@code null} * but is not expected to contain {@code null} elements) * @return the unique int result * @throws IncorrectResultSizeDataAccessException if more than one * result object has been found in the given Collection * @throws EmptyResultDataAccessException if no result object * at all has been found in the given Collection * @throws TypeMismatchDataAccessException if the unique object * in the collection is not convertible to an int */
public static int intResult(@Nullable Collection<?> results) throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException { return objectResult(results, Number.class).intValue(); }
Return a unique long result from the given Collection. Throws an exception if 0 or more than 1 result objects found, of if the unique result object is not convertible to a long.
Params:
  • results – the result Collection (can be null but is not expected to contain null elements)
Throws:
Returns:the unique long result
/** * Return a unique long result from the given Collection. * Throws an exception if 0 or more than 1 result objects found, * of if the unique result object is not convertible to a long. * @param results the result Collection (can be {@code null} * but is not expected to contain {@code null} elements) * @return the unique long result * @throws IncorrectResultSizeDataAccessException if more than one * result object has been found in the given Collection * @throws EmptyResultDataAccessException if no result object * at all has been found in the given Collection * @throws TypeMismatchDataAccessException if the unique object * in the collection is not convertible to a long */
public static long longResult(@Nullable Collection<?> results) throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException { return objectResult(results, Number.class).longValue(); }
Return a translated exception if this is appropriate, otherwise return the given exception as-is.
Params:
  • rawException – an exception that we may wish to translate
  • pet – the PersistenceExceptionTranslator to use to perform the translation
Returns:a translated persistence exception if translation is possible, or the raw exception if it is not
/** * Return a translated exception if this is appropriate, * otherwise return the given exception as-is. * @param rawException an exception that we may wish to translate * @param pet the PersistenceExceptionTranslator to use to perform the translation * @return a translated persistence exception if translation is possible, * or the raw exception if it is not */
public static RuntimeException translateIfNecessary( RuntimeException rawException, PersistenceExceptionTranslator pet) { Assert.notNull(pet, "PersistenceExceptionTranslator must not be null"); DataAccessException dae = pet.translateExceptionIfPossible(rawException); return (dae != null ? dae : rawException); } }