Skip to content

Commit

Permalink
Enforce non-null value in requiredSingleResult/requiredUniqueResult
Browse files Browse the repository at this point in the history
Closes gh-33300
  • Loading branch information
jhoeller committed Aug 5, 2024
1 parent 1e804d8 commit 28668d7
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -167,7 +167,11 @@ public static <T> T requiredSingleResult(@Nullable Collection<T> results) throws
if (results.size() > 1) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
T result = results.iterator().next();
if (result == null) {
throw new TypeMismatchDataAccessException("Result value is null but no null value expected");
}
return result;
}

/**
Expand Down Expand Up @@ -235,7 +239,11 @@ public static <T> T requiredUniqueResult(@Nullable Collection<T> results) throws
if (!CollectionUtils.hasUniqueObject(results)) {
throw new IncorrectResultSizeDataAccessException(1, results.size());
}
return results.iterator().next();
T result = results.iterator().next();
if (result == null) {
throw new TypeMismatchDataAccessException("Result value is null but no null value expected");
}
return result;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -52,21 +52,25 @@ void withEmptyCollection() {
assertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();
assertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.requiredUniqueResult(col))
.satisfies(sizeRequirements(1, 0));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.requiredSingleResult(col))
.satisfies(sizeRequirements(1, 0));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.objectResult(col, String.class))
.satisfies(sizeRequirements(1, 0));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.requiredUniqueResult(col))
.satisfies(sizeRequirements(1, 0));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.intResult(col))
.satisfies(sizeRequirements(1, 0));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.objectResult(col, String.class))
.satisfies(sizeRequirements(1, 0));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.intResult(col))
.satisfies(sizeRequirements(1, 0));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.longResult(col))
.satisfies(sizeRequirements(1, 0));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.longResult(col))
.satisfies(sizeRequirements(1, 0));
}

@Test
Expand All @@ -75,49 +79,83 @@ void withTooLargeCollection() {
col.add("test1");
col.add("test2");

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.uniqueResult(col))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.uniqueResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.requiredUniqueResult(col))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.requiredUniqueResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.objectResult(col, String.class))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.objectResult(col, String.class))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.intResult(col))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.intResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.longResult(col))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.longResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.requiredSingleResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.singleResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.singleResult(col.stream()))
.satisfies(sizeRequirements(1));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.singleResult(col.iterator()))
.satisfies(sizeRequirements(1));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.singleResult(col))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.optionalResult(col))
.satisfies(sizeRequirements(1, 2));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.optionalResult(col.stream()))
.satisfies(sizeRequirements(1));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.optionalResult(col.iterator()))
.satisfies(sizeRequirements(1));
}

@Test
void withNullValueInCollection() {
Collection<String> col = new HashSet<>();
col.add(null);

assertThat(DataAccessUtils.uniqueResult(col)).isNull();

assertThat(DataAccessUtils.singleResult(col)).isNull();
assertThat(DataAccessUtils.singleResult(col.stream())).isNull();
assertThat(DataAccessUtils.singleResult(col.iterator())).isNull();
assertThat(DataAccessUtils.optionalResult(col)).isEmpty();
assertThat(DataAccessUtils.optionalResult(col.stream())).isEmpty();
assertThat(DataAccessUtils.optionalResult(col.iterator())).isEmpty();

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.singleResult(col.stream()))
.satisfies(sizeRequirements(1));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.requiredSingleResult(col));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.singleResult(col.iterator()))
.satisfies(sizeRequirements(1));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.requiredUniqueResult(col));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.optionalResult(col))
.satisfies(sizeRequirements(1, 2));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.objectResult(col, String.class));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.optionalResult(col.stream()))
.satisfies(sizeRequirements(1));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.intResult(col));

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class).isThrownBy(() ->
DataAccessUtils.optionalResult(col.iterator()))
.satisfies(sizeRequirements(1));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.longResult(col));
}

@Test
Expand All @@ -131,6 +169,7 @@ void withInteger() {
assertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo("5");
assertThat(DataAccessUtils.intResult(col)).isEqualTo(5);
assertThat(DataAccessUtils.longResult(col)).isEqualTo(5);
assertThat(DataAccessUtils.requiredSingleResult(col)).isEqualTo(Integer.valueOf(5));
assertThat(DataAccessUtils.singleResult(col)).isEqualTo(5);
assertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(5);
assertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(5);
Expand Down Expand Up @@ -159,8 +198,8 @@ void withEquivalentIntegerInstanceTwice() {
Collection<Integer> col = Arrays.asList(555, 555);

assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.uniqueResult(col))
.satisfies(sizeRequirements(1, 2));
.isThrownBy(() -> DataAccessUtils.uniqueResult(col))
.satisfies(sizeRequirements(1, 2));
}

@Test
Expand All @@ -174,6 +213,7 @@ void withLong() {
assertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo("5");
assertThat(DataAccessUtils.intResult(col)).isEqualTo(5);
assertThat(DataAccessUtils.longResult(col)).isEqualTo(5);
assertThat(DataAccessUtils.requiredSingleResult(col)).isEqualTo(Long.valueOf(5L));
assertThat(DataAccessUtils.singleResult(col)).isEqualTo(Long.valueOf(5L));
assertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(Long.valueOf(5L));
assertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(Long.valueOf(5L));
Expand All @@ -190,18 +230,19 @@ void withString() {
assertThat(DataAccessUtils.uniqueResult(col)).isEqualTo("test1");
assertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo("test1");
assertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo("test1");
assertThat(DataAccessUtils.requiredSingleResult(col)).isEqualTo("test1");
assertThat(DataAccessUtils.singleResult(col)).isEqualTo("test1");
assertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo("test1");
assertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo("test1");
assertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of("test1"));
assertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of("test1"));
assertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of("test1"));

assertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->
DataAccessUtils.intResult(col));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.intResult(col));

assertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->
DataAccessUtils.longResult(col));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.longResult(col));
}

@Test
Expand All @@ -214,18 +255,19 @@ void withDate() {
assertThat(DataAccessUtils.requiredUniqueResult(col)).isEqualTo(date);
assertThat(DataAccessUtils.objectResult(col, Date.class)).isEqualTo(date);
assertThat(DataAccessUtils.objectResult(col, String.class)).isEqualTo(date.toString());
assertThat(DataAccessUtils.requiredSingleResult(col)).isEqualTo(date);
assertThat(DataAccessUtils.singleResult(col)).isEqualTo(date);
assertThat(DataAccessUtils.singleResult(col.stream())).isEqualTo(date);
assertThat(DataAccessUtils.singleResult(col.iterator())).isEqualTo(date);
assertThat(DataAccessUtils.optionalResult(col)).isEqualTo(Optional.of(date));
assertThat(DataAccessUtils.optionalResult(col.stream())).isEqualTo(Optional.of(date));
assertThat(DataAccessUtils.optionalResult(col.iterator())).isEqualTo(Optional.of(date));

assertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->
DataAccessUtils.intResult(col));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.intResult(col));

assertThatExceptionOfType(TypeMismatchDataAccessException.class).isThrownBy(() ->
DataAccessUtils.longResult(col));
assertThatExceptionOfType(TypeMismatchDataAccessException.class)
.isThrownBy(() -> DataAccessUtils.longResult(col));
}

@Test
Expand Down

1 comment on commit 28668d7

@123Wudi

This comment was marked as spam.

Please sign in to comment.