Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.1.0.BUILD-SNAPSHOT</version>
<version>1.1.0.DATAJDBC-273-SNAPSHOT</version>

<name>Spring Data JDBC</name>
<description>Spring Data module for JDBC repositories.</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,16 @@ public EntityRowMapper(RelationalPersistentEntity<T> entity, RelationalMappingCo
@Override
public T mapRow(ResultSet resultSet, int rowNumber) {

T result = createInstance(entity, resultSet, "");
String prefix = "";

RelationalPersistentProperty idProperty = entity.getIdProperty();

Object idValue = null;
if (idProperty != null) {
idValue = readFrom(resultSet, idProperty, prefix);
}

T result = createInstance(entity, resultSet, idValue);

return entity.requiresPropertyPopulation() //
? populateProperties(result, resultSet) //
Expand All @@ -88,26 +97,24 @@ private T populateProperties(T result, ResultSet resultSet) {
continue;
}

if (property.isCollectionLike() && id != null) {

propertyAccessor.setProperty(property, accessStrategy.findAllByProperty(id, property));

} else if (property.isMap() && id != null) {

Iterable<Object> allByProperty = accessStrategy.findAllByProperty(id, property);
propertyAccessor.setProperty(property, ITERABLE_OF_ENTRY_TO_MAP_CONVERTER.convert(allByProperty));

} else {

final Object value = readFrom(resultSet, property, "");

propertyAccessor.setProperty(property, value);
}
propertyAccessor.setProperty(property, readOrLoadProperty(resultSet, id, property));
}

return propertyAccessor.getBean();
}

@Nullable
private Object readOrLoadProperty(ResultSet resultSet, @Nullable Object id, RelationalPersistentProperty property) {

if (property.isCollectionLike() && id != null) {
return accessStrategy.findAllByProperty(id, property);
} else if (property.isMap() && id != null) {
return ITERABLE_OF_ENTRY_TO_MAP_CONVERTER.convert(accessStrategy.findAllByProperty(id, property));
} else {
return readFrom(resultSet, property, "");
}
}

/**
* Read a single value or a complete Entity from the {@link ResultSet} passed as an argument.
*
Expand Down Expand Up @@ -139,14 +146,20 @@ private <S> S readEntityFrom(ResultSet rs, RelationalPersistentProperty property

RelationalPersistentProperty idProperty = entity.getIdProperty();

Object idValue = null;

if (idProperty != null) {
idValue = readFrom(rs, idProperty, prefix);
}

if ((idProperty != null //
? readFrom(rs, idProperty, prefix) //
? idValue //
: getObjectFromResultSet(rs, prefix + property.getReverseColumnName()) //
) == null) {
return null;
}

S instance = createInstance(entity, rs, prefix);
S instance = createInstance(entity, rs, idValue);

PersistentPropertyAccessor<S> accessor = converter.getPropertyAccessor(entity, instance);

Expand All @@ -167,7 +180,7 @@ private Object getObjectFromResultSet(ResultSet rs, String backreferenceName) {
}
}

private <S> S createInstance(RelationalPersistentEntity<S> entity, ResultSet rs, String prefix) {
private <S> S createInstance(RelationalPersistentEntity<S> entity, ResultSet rs, @Nullable Object idValue) {

return converter.createInstance(entity, parameter -> {

Expand All @@ -176,7 +189,8 @@ private <S> S createInstance(RelationalPersistentEntity<S> entity, ResultSet rs,
Assert.notNull(parameterName, "A constructor parameter name must not be null to be used with Spring Data JDBC");

RelationalPersistentProperty property = entity.getRequiredPersistentProperty(parameterName);
return readFrom(rs, property, prefix);

return readOrLoadProperty(rs, idValue, property);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Wither;

Expand Down Expand Up @@ -201,6 +202,18 @@ public void handlesMixedProperties() throws SQLException {
.isEqualTo(new String[] { "111", "222", "333" });
}

@Test // DATAJDBC-273
public void handlesNonSimplePropertyInConstructor() throws SQLException {

ResultSet rs = mockResultSet(asList("id"), //
ID_FOR_ENTITY_REFERENCING_LIST);
rs.next();

EntityWithListInConstructor extracted = createRowMapper(EntityWithListInConstructor.class).mapRow(rs, 1);

assertThat(extracted.content).hasSize(2);
}

private <T> EntityRowMapper<T> createRowMapper(Class<T> type) {
return createRowMapper(type, NamingStrategy.INSTANCE);
}
Expand Down Expand Up @@ -246,7 +259,7 @@ private static ResultSet mockResultSet(List<String> columns, Object... values) {
"Number of values [%d] must be a multiple of the number of columns [%d]", //
values.length, //
columns.size() //
) //
) //
);

List<Map<String, Object>> result = convertValues(columns, values);
Expand Down Expand Up @@ -318,12 +331,13 @@ private boolean isBeforeFirst() {
return index < 0 && !values.isEmpty();
}

private Object getObject(String column) {
private Object getObject(String column) throws SQLException {

Map<String, Object> rowMap = values.get(index);

Assert.isTrue(rowMap.containsKey(column),
String.format("Trying to access a column (%s) that does not exist", column));
if (!rowMap.containsKey(column)) {
throw new SQLException(String.format("Trying to access a column (%s) that does not exist", column));
}

return rowMap.get(column);
}
Expand Down Expand Up @@ -408,4 +422,12 @@ MixedProperties withThree(String three) {
return new MixedProperties(one, two, three);
}
}

@AllArgsConstructor
static class EntityWithListInConstructor {

@Id final Long id;

final List<Trivial> content;
}
}