Polish JDBC KeyHolder support

See gh-24655
This commit is contained in:
Sam Brannen
2020-06-16 14:17:43 +02:00
parent b50cf9dad2
commit cc301011b2
3 changed files with 69 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* 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.
@@ -66,25 +66,25 @@ public class GeneratedKeyHolder implements KeyHolder {
@Override
@Nullable
public <T> T getKeyAs(Class<T> keyClass) throws InvalidDataAccessApiUsageException, DataRetrievalFailureException {
public <T> T getKeyAs(Class<T> keyType) throws InvalidDataAccessApiUsageException, DataRetrievalFailureException {
if (this.keyList.isEmpty()) {
return null;
}
if (this.keyList.size() > 1 || this.keyList.get(0).size() > 1) {
throw new InvalidDataAccessApiUsageException(
"The getKey method should only be used when a single key is returned. " +
"The getKey method should only be used when a single key is returned. " +
"The current key entry contains multiple keys: " + this.keyList);
}
Iterator<Object> keyIter = this.keyList.get(0).values().iterator();
if (keyIter.hasNext()) {
Object key = keyIter.next();
if (key == null || !(keyClass.isAssignableFrom(key.getClass()))) {
if (key == null || !(keyType.isAssignableFrom(key.getClass()))) {
throw new DataRetrievalFailureException(
"The generated key is not of a supported type. " +
"The generated key type is not supported. " +
"Unable to cast [" + (key != null ? key.getClass().getName() : null) +
"] to [" + keyClass.getName() + "]");
"] to [" + keyType.getName() + "].");
}
return keyClass.cast(key);
return keyType.cast(key);
}
else {
throw new DataRetrievalFailureException("Unable to retrieve the generated key. " +
@@ -100,7 +100,7 @@ public class GeneratedKeyHolder implements KeyHolder {
}
if (this.keyList.size() > 1) {
throw new InvalidDataAccessApiUsageException(
"The getKeys method should only be used when keys for a single row are returned. " +
"The getKeys method should only be used when keys for a single row are returned. " +
"The current key list contains keys for multiple rows: " + this.keyList);
}
return this.keyList.get(0);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* 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.
@@ -31,9 +31,10 @@ import org.springframework.lang.Nullable;
* for each row of keys.
*
* <p>Most applications only use one key per row and process only one row at a
* time in an insert statement. In these cases, just call {@code getKey}
* to retrieve the key. The returned value is a Number here, which is the
* usual type for auto-generated keys.
* time in an insert statement. In these cases, just call {@link #getKey() getKey}
* or {@link #getKeyAs(Class) getKeyAs} to retrieve the key. The value returned
* by {@code getKey} is a {@link Number}, which is the usual type for auto-generated
* keys. For any other auto-generated key type, use {@code getKeyAs} instead.
*
* @author Thomas Risberg
* @author Juergen Hoeller
@@ -54,25 +55,28 @@ public interface KeyHolder {
* then an InvalidDataAccessApiUsageException is thrown.
* @return the generated key as a number
* @throws InvalidDataAccessApiUsageException if multiple keys are encountered
* @see #getKeyAs(Class)
*/
@Nullable
Number getKey() throws InvalidDataAccessApiUsageException;
/**
* Retrieve the first item from the first map, assuming that there is just
* one item and just one map, and that the item is an instance of provided class.
* This is the typical case: a single generated key of desired class.
* one item and just one map, and that the item is an instance of specified type.
* This is a common case: a single generated key of the specified type.
* <p>Keys are held in a List of Maps, where each item in the list represents
* the keys for each row. If there are multiple columns, then the Map will have
* multiple entries as well. If this method encounters multiple entries in
* either the map or the list meaning that multiple keys were returned,
* then an InvalidDataAccessApiUsageException is thrown.
* @param keyClass class of the requested key
* @return the generated key as an instance of provided class
* @param keyType the type of the auto-generated key
* @return the generated key as an instance of specified type
* @throws InvalidDataAccessApiUsageException if multiple keys are encountered
* @since 5.3
* @see #getKey()
*/
@Nullable
<T> T getKeyAs(Class<T> keyClass) throws InvalidDataAccessApiUsageException;
<T> T getKeyAs(Class<T> keyType) throws InvalidDataAccessApiUsageException;
/**
* Retrieve the first map of keys.