DATAJDBC-341 - Map NULL values in EntityRowMapper for columns not being fetched in the query.
Original pull request: #170.
This commit is contained in:
committed by
Jens Schauder
parent
6769528068
commit
c2062dbb9d
@@ -59,10 +59,10 @@ import org.springframework.util.Assert;
|
||||
* @author Jens Schauder
|
||||
* @author Christoph Strobl
|
||||
* @author Myeonghyeon Lee
|
||||
* @since 1.1
|
||||
* @see MappingContext
|
||||
* @see SimpleTypeHolder
|
||||
* @see CustomConversions
|
||||
* @since 1.1
|
||||
*/
|
||||
public class BasicJdbcConverter extends BasicRelationalConverter implements JdbcConverter {
|
||||
|
||||
@@ -401,7 +401,35 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
|
||||
continue;
|
||||
}
|
||||
|
||||
propertyAccessor.setProperty(property, readOrLoadProperty(idValue, property));
|
||||
// check if property is in the result set
|
||||
// if not - leave it out
|
||||
// DATAJDBC-341
|
||||
if (property.isEntity() || property.isEmbedded()) {
|
||||
propertyAccessor.setProperty(property, readOrLoadProperty(idValue, property));
|
||||
} else {
|
||||
try {
|
||||
if (resultSet.findColumn(property.getColumnName().getReference(identifierProcessing)) > 0) {
|
||||
propertyAccessor.setProperty(property, readOrLoadProperty(idValue, property));
|
||||
} else {
|
||||
try {
|
||||
propertyAccessor.setProperty(property, readOrLoadProperty(idValue, property));
|
||||
} catch (Exception exception) {
|
||||
LOG.info(
|
||||
"The result set is not corresponding to the target entity. Left out properties will be set to standard values (NULL for reference types, 0 for primitives.");
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
String columnAlias = path.extendBy(property).getColumnAlias().getReference(identifierProcessing);
|
||||
try {
|
||||
if (resultSet.findColumn(columnAlias) > 0) {
|
||||
propertyAccessor.setProperty(property, readOrLoadProperty(idValue, property));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LOG.info(String.format("Cannot find column named %s within the result set!", property.getColumnName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return propertyAccessor.getBean();
|
||||
@@ -523,7 +551,8 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
|
||||
try {
|
||||
return resultSet.getObject(backreferenceName);
|
||||
} catch (SQLException o_O) {
|
||||
throw new MappingException(String.format("Could not read value %s from result set!", backreferenceName), o_O);
|
||||
LOG.info(String.format("Could not read value %s from result set! Use null as value.", backreferenceName), o_O);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,7 @@ import lombok.With;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -87,6 +83,35 @@ public class EntityRowMapperUnitTests {
|
||||
}
|
||||
};
|
||||
|
||||
@Test // DATAJDBC-341
|
||||
public void mapNotNeededValueTypePropertiesToNull() throws SQLException {
|
||||
ResultSet rs = mockResultSet(singletonList("id"), //
|
||||
ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
|
||||
rs.next();
|
||||
Trivial extracted = createRowMapper(Trivial.class).mapRow(rs, 1);
|
||||
|
||||
assertThat(extracted) //
|
||||
.isNotNull() //
|
||||
.extracting(e -> e.id, e -> e.name) //
|
||||
.containsExactly(ID_FOR_ENTITY_NOT_REFERENCING_MAP, null);
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-341
|
||||
public void mapNotNeededPrimitiveTypePropertiesToNull() throws SQLException {
|
||||
ResultSet rs = mockResultSet(singletonList("id"), //
|
||||
ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
|
||||
rs.next();
|
||||
TrivialMapPropertiesToNullIfNotNeeded extracted = createRowMapper(TrivialMapPropertiesToNullIfNotNeeded.class)
|
||||
.mapRow(rs, 1);
|
||||
|
||||
assertThat(extracted) //
|
||||
.isNotNull() //
|
||||
.extracting(e -> e.id, e -> e.age) //
|
||||
.containsExactly(ID_FOR_ENTITY_NOT_REFERENCING_MAP, 0);
|
||||
|
||||
}
|
||||
|
||||
@Test // DATAJDBC-113
|
||||
public void simpleEntitiesGetProperlyExtracted() throws SQLException {
|
||||
|
||||
@@ -477,6 +502,19 @@ public class EntityRowMapperUnitTests {
|
||||
String name;
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
static class TrivialMapPropertiesToNullIfNotNeeded {
|
||||
|
||||
@Id Long id;
|
||||
int age;
|
||||
String phone;
|
||||
Boolean isSupreme;
|
||||
long referenceToCustomer;
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@@ -762,11 +800,18 @@ public class EntityRowMapperUnitTests {
|
||||
return isAfterLast() || isBeforeFirst() ? 0 : index + 1;
|
||||
case "toString":
|
||||
return this.toString();
|
||||
case "findColumn":
|
||||
return isThereAColumnNamed(invocation.getArgument(0));
|
||||
default:
|
||||
throw new OperationNotSupportedException(invocation.getMethod().getName());
|
||||
}
|
||||
}
|
||||
|
||||
private int isThereAColumnNamed(String name) {
|
||||
Optional<Map<String, Object>> first = values.stream().filter(s -> s.equals(name)).findFirst();
|
||||
return (first.isPresent()) ? 1 : 0;
|
||||
}
|
||||
|
||||
private boolean isAfterLast() {
|
||||
return index >= values.size() && !values.isEmpty();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user