Skip to content

Commit

Permalink
fix(#2932): remove ability to partially specify property name for con…
Browse files Browse the repository at this point in the history
…structor args

- see  #3378 (comment)
  • Loading branch information
epochcoder committed Jan 15, 2025
1 parent 45716cf commit be848e4
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public List<ResultMapping> resolveWithConstructor() {
.filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));

// arg order can only be 'fixed' if all mappings have property names
final boolean allMappingsHavePropertyNames = constructorResultMappings.size() == constructorArgsByName.size();
final boolean allMappingsHavePropertyNames = verifyPropertyNaming(constructorArgsByName);

// only do this if all property mappings were set
if (allMappingsHavePropertyNames) {
Expand Down Expand Up @@ -147,6 +147,19 @@ public List<ResultMapping> resolveWithConstructor() {
return resultMappings;
}

private boolean verifyPropertyNaming(Set<String> constructorArgsByName) {
final boolean allMappingsHavePropertyNames = constructorResultMappings.size() == constructorArgsByName.size();

// If property names have been partially specified, throw an exception, as this case does not make sense
// either specify all names and (optional random order), or type info.
if (!allMappingsHavePropertyNames && !constructorArgsByName.isEmpty()) {
throw new BuilderException("Error in result map '" + resultMapId
+ "'. We do not support partially specifying a property name. Either specify all property names, or none.");
}

return allMappingsHavePropertyNames;
}

List<ConstructorMetaInfo> retrieveConstructorCandidates(int withLength) {
return Arrays.stream(resultType.getDeclaredConstructors())
.filter(constructor -> constructor.getParameterTypes().length == withLength).map(ConstructorMetaInfo::new)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,16 @@ void testReturnOriginalMappingsWhenNoPropertyNamesDefinedAndCannotResolveConstru
}

@Test
void testCanResolveWithMissingPropertyNameAndPartialTypeInfo() {
void testThrowExceptionWithPartialPropertyNameSpecified() {
ResultMapping mappingA = createConstructorMappingFor(Object.class, "a", "a");
ResultMapping mappingB = createConstructorMappingFor(Object.class, null, "b");
ResultMapping mappingC = createConstructorMappingFor(LocalDate.class, null, "c");
ResultMapping[] constructorMappings = new ResultMapping[] { mappingA, mappingB, mappingC };

final ResultMappingConstructorResolver resolver = createResolverFor(ResultType1.class, TEST_ID,
constructorMappings);
final List<ResultMapping> mappingList = resolver.resolveWithConstructor();
final ResultMappingConstructorResolver resolver = createResolverFor(ResultType1.class, TEST_ID, mappingA, mappingB,
mappingC);

assertThat(mappingList).extracting(ResultMapping::getProperty, mapping -> mapping.getJavaType().getSimpleName())
.containsExactly(tuple("a", "long"), tuple(null, "String"), tuple(null, "LocalDate"));
assertThatThrownBy(resolver::resolveWithConstructor).isInstanceOf(BuilderException.class)
.hasMessageContaining("Either specify all property names, or none.");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ public interface Mapper1 {
String SELECT_SQL = "select a.id, a.name, a.type from account a where a.id = #{id}";
String SELECT_WITH_DOB_SQL = "select id, name, type, date '2025-01-05' dob from account where id = #{id}";

@ConstructorArgs({ @Arg(column = "id"), @Arg(column = "name"), @Arg(column = "type")})
@ConstructorArgs({ @Arg(column = "id"), @Arg(column = "name"), @Arg(column = "type") })
@Select(SELECT_SQL)
Account getAccountJavaTypesMissing(long id);

@ConstructorArgs({ @Arg(column = "id"), @Arg(column = "name", javaType = String.class), @Arg(column = "type")})
@ConstructorArgs({ @Arg(column = "id"), @Arg(column = "name", javaType = String.class), @Arg(column = "type") })
@Select(SELECT_SQL)
Account3 getAccountPartialTypesProvided(long id);

Expand Down

0 comments on commit be848e4

Please sign in to comment.