下面列出了org.springframework.core.convert.ConverterNotFoundException#org.springframework.dao.TypeMismatchDataAccessException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
@Nullable
public Object readValueForProperty(@Nullable Value value, TypeInformation<?> type) {
boolean valueIsLiteralNullOrNullValue = value == null || value == Values.NULL;
try {
Class<?> rawType = type.getType();
if (!valueIsLiteralNullOrNullValue && isCollection(type)) {
Collection<Object> target = createCollection(rawType, type.getComponentType().getType(), value.size());
value.values().forEach(
element -> target.add(conversionService.convert(element, type.getComponentType().getType())));
return target;
}
return conversionService.convert(valueIsLiteralNullOrNullValue ? null : value, rawType);
} catch (Exception e) {
String msg = String.format("Could not convert %s into %s", value, type.toString());
throw new TypeMismatchDataAccessException(msg, e);
}
}
/**
* 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) && Number.class.isInstance(result)) {
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 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) && Number.class.isInstance(result)) {
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;
}
/**
* Extract a value for the single column in the current row.
* <p>Validates that there is only one column selected,
* then delegates to {@code getColumnValue()} and also
* {@code convertValueToRequiredType}, if necessary.
* @see java.sql.ResultSetMetaData#getColumnCount()
* @see #getColumnValue(java.sql.ResultSet, int, Class)
* @see #convertValueToRequiredType(Object, Class)
*/
@Override
@SuppressWarnings("unchecked")
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
// Validate column count.
ResultSetMetaData rsmd = rs.getMetaData();
int nrOfColumns = rsmd.getColumnCount();
if (nrOfColumns != 1) {
throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
}
// Extract column value from JDBC ResultSet.
Object result = getColumnValue(rs, 1, this.requiredType);
if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
// Extracted value does not match already: try to convert it.
try {
return (T) convertValueToRequiredType(result, this.requiredType);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchDataAccessException(
"Type mismatch affecting row number " + rowNum + " and column type '" +
rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
}
}
return (T) result;
}
/**
* 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})
* @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(Collection<?> results, 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) && Number.class.isInstance(result)) {
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 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 convertable to the
* specified required type.
* @param results the result Collection (can be {@code null})
* @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(Collection<?> results, 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) && Number.class.isInstance(result)) {
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;
}
/**
* Extract a value for the single column in the current row.
* <p>Validates that there is only one column selected,
* then delegates to {@code getColumnValue()} and also
* {@code convertValueToRequiredType}, if necessary.
* @see java.sql.ResultSetMetaData#getColumnCount()
* @see #getColumnValue(java.sql.ResultSet, int, Class)
* @see #convertValueToRequiredType(Object, Class)
*/
@Override
@SuppressWarnings("unchecked")
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
// Validate column count.
ResultSetMetaData rsmd = rs.getMetaData();
int nrOfColumns = rsmd.getColumnCount();
if (nrOfColumns != 1) {
throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
}
// Extract column value from JDBC ResultSet.
Object result = getColumnValue(rs, 1, this.requiredType);
if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
// Extracted value does not match already: try to convert it.
try {
return (T) convertValueToRequiredType(result, this.requiredType);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchDataAccessException(
"Type mismatch affecting row number " + rowNum + " and column type '" +
rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
}
}
return (T) result;
}
/**
* Extract a value for the single column in the current row.
* <p>Validates that there is only one column selected,
* then delegates to {@code getColumnValue()} and also
* {@code convertValueToRequiredType}, if necessary.
* @see java.sql.ResultSetMetaData#getColumnCount()
* @see #getColumnValue(java.sql.ResultSet, int, Class)
* @see #convertValueToRequiredType(Object, Class)
*/
@Override
@SuppressWarnings("unchecked")
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
// Validate column count.
ResultSetMetaData rsmd = rs.getMetaData();
int nrOfColumns = rsmd.getColumnCount();
if (nrOfColumns != 1) {
throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
}
// Extract column value from JDBC ResultSet.
Object result = getColumnValue(rs, 1, this.requiredType);
if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
// Extracted value does not match already: try to convert it.
try {
return (T) convertValueToRequiredType(result, this.requiredType);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchDataAccessException(
"Type mismatch affecting row number " + rowNum + " and column type '" +
rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
}
}
return (T) result;
}
@Test
void shouldCatchConversionErrors() {
Value value = Values.value("Das funktioniert nicht.");
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> defaultNeo4jConverter.readValueForProperty(value, ClassTypeInformation.from(Date.class)))
.withMessageStartingWith("Could not convert \"Das funktioniert nicht.\" into java.util.Date;")
.withCauseInstanceOf(ConversionFailedException.class)
.withRootCauseInstanceOf(DateTimeParseException.class);
}
@Test
void shouldCatchUncoercibleErrors() {
Value value = Values.value("Das funktioniert nicht.");
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> defaultNeo4jConverter.readValueForProperty(value, ClassTypeInformation.from(LocalDate.class)))
.withMessageStartingWith("Could not convert \"Das funktioniert nicht.\" into java.time.LocalDate;")
.withCauseInstanceOf(ConversionFailedException.class)
.withRootCauseInstanceOf(Uncoercible.class);
}
@Test
void shouldCatchUncoerfcibleErrors() {
Value value = Values.value("Das funktioniert nicht.");
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(
() -> defaultNeo4jConverter.readValueForProperty(value, ClassTypeInformation.from(ReactiveNeo4jClient.class)))
.withMessageStartingWith(
"Could not convert \"Das funktioniert nicht.\" into org.neo4j.springframework.data.core.ReactiveNeo4jClient;")
.withRootCauseInstanceOf(ConverterNotFoundException.class);
}
/**
* Analogous to the SqlQuery.execute([]) method. This is a
* generic method to execute a query, taken a number of arguments.
* @param parameters array of parameters. These will be objects or
* object wrapper types for primitives.
* @return the value of the function
*/
public int run(Object... parameters) {
Object obj = super.findObject(parameters);
if (!(obj instanceof Number)) {
throw new TypeMismatchDataAccessException("Couldn't convert result object [" + obj + "] to int");
}
return ((Number) obj).intValue();
}
/**
* Extract a value for the single column in the current row.
* <p>Validates that there is only one column selected,
* then delegates to {@code getColumnValue()} and also
* {@code convertValueToRequiredType}, if necessary.
* @see java.sql.ResultSetMetaData#getColumnCount()
* @see #getColumnValue(java.sql.ResultSet, int, Class)
* @see #convertValueToRequiredType(Object, Class)
*/
@Override
@SuppressWarnings("unchecked")
@Nullable
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
// Validate column count.
ResultSetMetaData rsmd = rs.getMetaData();
int nrOfColumns = rsmd.getColumnCount();
if (nrOfColumns != 1) {
throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
}
// Extract column value from JDBC ResultSet.
Object result = getColumnValue(rs, 1, this.requiredType);
if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
// Extracted value does not match already: try to convert it.
try {
return (T) convertValueToRequiredType(result, this.requiredType);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchDataAccessException(
"Type mismatch affecting row number " + rowNum + " and column type '" +
rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
}
}
return (T) result;
}
@Test(expected = TypeMismatchDataAccessException.class) // SPR-16483
public void doesNotUseConversionService() throws SQLException {
SingleColumnRowMapper<LocalDateTime> rowMapper =
SingleColumnRowMapper.newInstance(LocalDateTime.class, null);
ResultSet resultSet = mock(ResultSet.class);
ResultSetMetaData metaData = mock(ResultSetMetaData.class);
given(metaData.getColumnCount()).willReturn(1);
given(resultSet.getMetaData()).willReturn(metaData);
given(resultSet.getObject(1, LocalDateTime.class))
.willThrow(new SQLFeatureNotSupportedException());
given(resultSet.getTimestamp(1)).willReturn(new Timestamp(0));
rowMapper.mapRow(resultSet, 1);
}
/**
* Analogous to the SqlQuery.execute([]) method. This is a
* generic method to execute a query, taken a number of arguments.
* @param parameters array of parameters. These will be objects or
* object wrapper types for primitives.
* @return the value of the function
*/
public int run(Object... parameters) {
Object obj = super.findObject(parameters);
if (!(obj instanceof Number)) {
throw new TypeMismatchDataAccessException("Couldn't convert result object [" + obj + "] to int");
}
return ((Number) obj).intValue();
}
/**
* Extract a value for the single column in the current row.
* <p>Validates that there is only one column selected,
* then delegates to {@code getColumnValue()} and also
* {@code convertValueToRequiredType}, if necessary.
* @see java.sql.ResultSetMetaData#getColumnCount()
* @see #getColumnValue(java.sql.ResultSet, int, Class)
* @see #convertValueToRequiredType(Object, Class)
*/
@Override
@SuppressWarnings("unchecked")
@Nullable
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
// Validate column count.
ResultSetMetaData rsmd = rs.getMetaData();
int nrOfColumns = rsmd.getColumnCount();
if (nrOfColumns != 1) {
throw new IncorrectResultSetColumnCountException(1, nrOfColumns);
}
// Extract column value from JDBC ResultSet.
Object result = getColumnValue(rs, 1, this.requiredType);
if (result != null && this.requiredType != null && !this.requiredType.isInstance(result)) {
// Extracted value does not match already: try to convert it.
try {
return (T) convertValueToRequiredType(result, this.requiredType);
}
catch (IllegalArgumentException ex) {
throw new TypeMismatchDataAccessException(
"Type mismatch affecting row number " + rowNum + " and column type '" +
rsmd.getColumnTypeName(1) + "': " + ex.getMessage());
}
}
return (T) result;
}
@Test(expected = TypeMismatchDataAccessException.class) // SPR-16483
public void doesNotUseConversionService() throws SQLException {
SingleColumnRowMapper<LocalDateTime> rowMapper =
SingleColumnRowMapper.newInstance(LocalDateTime.class, null);
ResultSet resultSet = mock(ResultSet.class);
ResultSetMetaData metaData = mock(ResultSetMetaData.class);
given(metaData.getColumnCount()).willReturn(1);
given(resultSet.getMetaData()).willReturn(metaData);
given(resultSet.getObject(1, LocalDateTime.class))
.willThrow(new SQLFeatureNotSupportedException());
given(resultSet.getTimestamp(1)).willReturn(new Timestamp(0));
rowMapper.mapRow(resultSet, 1);
}
/**
* Analogous to the SqlQuery.execute([]) method. This is a
* generic method to execute a query, taken a number of arguments.
* @param parameters array of parameters. These will be objects or
* object wrapper types for primitives.
* @return the value of the function
*/
public int run(Object... parameters) {
Object obj = super.findObject(parameters);
if (!(obj instanceof Number)) {
throw new TypeMismatchDataAccessException("Couldn't convert result object [" + obj + "] to int");
}
return ((Number) obj).intValue();
}
/**
* Analogous to the SqlQuery.execute([]) method. This is a
* generic method to execute a query, taken a number of arguments.
* @param parameters array of parameters. These will be objects or
* object wrapper types for primitives.
* @return the value of the function
*/
public int run(Object... parameters) {
Object obj = super.findObject(parameters);
if (!(obj instanceof Number)) {
throw new TypeMismatchDataAccessException("Couldn't convert result object [" + obj + "] to int");
}
return ((Number) obj).intValue();
}
/**
* Analogous to the SqlQuery.execute([]) method. This is a
* generic method to execute a query, taken a number of arguments.
* @param parameters array of parameters. These will be objects or
* object wrapper types for primitives.
* @return the value of the function
*/
public int run(Object... parameters) {
Object obj = super.findObject(parameters);
if (!(obj instanceof Number)) {
throw new TypeMismatchDataAccessException("Couldn't convert result object [" + obj + "] to int");
}
return ((Number) obj).intValue();
}
/**
* 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.
* @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 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.
* @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 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})
* @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(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.
* @param results the result Collection (can be {@code null})
* @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(Collection<?> results)
throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException {
return objectResult(results, Number.class).longValue();
}
/**
* 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 convertable to an int.
* @param results the result Collection (can be {@code null})
* @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 convertable to an int
*/
public static int intResult(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 convertable to a long.
* @param results the result Collection (can be {@code null})
* @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 convertable to a long
*/
public static long longResult(Collection<?> results)
throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException {
return objectResult(results, Number.class).longValue();
}