DATAJDBC-266 - Entities referenced by 1:1 don't need an Id.

The id-property was used to determine if there is an instance at all, or if it was null.
For entities that don't have an id that purpose is now fulfilled by selecting the backreference and checking it against null.

See also: DATAJDBC-223.
This commit is contained in:
Jens Schauder
2018-09-28 10:20:25 -04:00
committed by Greg Turnquist
parent f46a01dbd8
commit 0816f4182e
8 changed files with 126 additions and 13 deletions

View File

@@ -21,7 +21,6 @@ import java.util.Map;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.relational.core.conversion.RelationalConverter;
@@ -118,21 +117,17 @@ public class EntityRowMapper<T> implements RowMapper<T> {
@Nullable
private Object readFrom(ResultSet resultSet, RelationalPersistentProperty property, String prefix) {
try {
if (property.isEntity()) {
return readEntityFrom(resultSet, property);
}
return converter.readValue(resultSet.getObject(prefix + property.getColumnName()), property.getTypeInformation());
} catch (SQLException o_O) {
throw new MappingException(String.format("Could not read property %s from result set!", property), o_O);
if (property.isEntity()) {
return readEntityFrom(resultSet, property);
}
Object value = getObjectFromResultSet(resultSet, prefix + property.getColumnName());
return converter.readValue(value, property.getTypeInformation());
}
@Nullable
private <S> S readEntityFrom(ResultSet rs, PersistentProperty<?> property) {
private <S> S readEntityFrom(ResultSet rs, RelationalPersistentProperty property) {
String prefix = property.getName() + "_";
@@ -140,7 +135,12 @@ public class EntityRowMapper<T> implements RowMapper<T> {
RelationalPersistentEntity<S> entity = (RelationalPersistentEntity<S>) context
.getRequiredPersistentEntity(property.getActualType());
if (readFrom(rs, entity.getRequiredIdProperty(), prefix) == null) {
RelationalPersistentProperty idProperty = entity.getIdProperty();
if ((idProperty != null //
? readFrom(rs, idProperty, prefix) //
: getObjectFromResultSet(rs, prefix + property.getReverseColumnName()) //
) == null) {
return null;
}
@@ -155,6 +155,16 @@ public class EntityRowMapper<T> implements RowMapper<T> {
return instance;
}
@Nullable
private Object getObjectFromResultSet(ResultSet rs, String backreferenceName) {
try {
return rs.getObject(backreferenceName);
} catch (SQLException o_O) {
throw new MappingException(String.format("Could not read value %s from result set!", backreferenceName), o_O);
}
}
private <S> S createInstance(RelationalPersistentEntity<S> entity, ResultSet rs, String prefix) {
return converter.createInstance(entity, parameter -> {

View File

@@ -201,6 +201,17 @@ class SqlGenerator {
.as(joinAlias + "_" + refProperty.getColumnName()) //
);
}
// if the referenced property doesn't have an id, include the back reference in the select list.
// this enables determining if the referenced entity is present or null.
if (!refEntity.hasIdProperty()) {
builder.column( //
cb -> cb.tableAlias(joinAlias) //
.column(property.getReverseColumnName()) //
.as(joinAlias + "_" + property.getReverseColumnName()) //
);
}
}
}