Skip to content

DATAJDBC-181 - Use NamingStrategy for instantiating entities. #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
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 @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<version>1.0.0.DATAJDBC-181-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 @@ -16,6 +16,7 @@
package org.springframework.data.jdbc.core;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ClassGeneratingEntityInstantiator;
Expand Down Expand Up @@ -94,7 +95,7 @@ public T mapRow(ResultSet resultSet, int rowNumber) throws SQLException {
}

private T createInstance(ResultSet rs) {
return instantiator.createInstance(entity, ResultSetParameterValueProvider.of(rs, conversions, ""));
return instantiator.createInstance(entity, new ResultSetParameterValueProvider(rs, entity, conversions, ""));
}

private Object readFrom(ResultSet resultSet, JdbcPersistentProperty property, String prefix) {
Expand Down Expand Up @@ -123,7 +124,7 @@ private <S> S readEntityFrom(ResultSet rs, PersistentProperty<?> property) {
return null;
}

S instance = instantiator.createInstance(entity, ResultSetParameterValueProvider.of(rs, conversions, prefix));
S instance = instantiator.createInstance(entity, new ResultSetParameterValueProvider(rs, entity, conversions, prefix));

PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
ConvertingPropertyAccessor propertyAccessor = new ConvertingPropertyAccessor(accessor, conversions);
Expand All @@ -135,40 +136,27 @@ private <S> S readEntityFrom(ResultSet rs, PersistentProperty<?> property) {
return instance;
}

@RequiredArgsConstructor
private static class ResultSetParameterValueProvider implements ParameterValueProvider<JdbcPersistentProperty> {

@NonNull
private final ResultSet resultSet;
@NonNull
private final JdbcPersistentEntity<?> entity;
@NonNull
private final ConversionService conversionService;
@NonNull
private final String prefix;

private ResultSetParameterValueProvider(ResultSet resultSet, ConversionService conversionService, String prefix) {

this.resultSet = resultSet;
this.conversionService = conversionService;
this.prefix = prefix;
}

public static ResultSetParameterValueProvider of(ResultSet resultSet, ConversionService conversionService,
String prefix) {
return new ResultSetParameterValueProvider(resultSet, conversionService, prefix);
}

/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter)
*/
@Override
public <T> T getParameterValue(Parameter<T, JdbcPersistentProperty> parameter) {

String name = parameter.getName();
if (name == null) {
return null;
}
String column = prefix + entity.getRequiredPersistentProperty(parameter.getName()).getColumnName();

String column = prefix + name;
try {
return conversionService.convert(resultSet.getObject(column), parameter.getType().getType());
} catch (SQLException o_O) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.annotation.Id;
import org.springframework.data.convert.Jsr310Converters;
import org.springframework.data.jdbc.mapping.model.DefaultNamingStrategy;
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty;
import org.springframework.data.jdbc.mapping.model.NamingStrategy;
import org.springframework.data.repository.query.Param;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.util.Assert;

Expand Down Expand Up @@ -54,6 +57,12 @@ public class EntityRowMapperUnitTests {
public static final long ID_FOR_ENTITY_REFERENCING_MAP = 42L;
public static final long ID_FOR_ENTITY_REFERENCING_LIST = 4711L;
public static final long ID_FOR_ENTITY_NOT_REFERENCING_MAP = 23L;
public static final DefaultNamingStrategy X_APPENDING_NAMINGSTRATEGY = new DefaultNamingStrategy() {
@Override
public String getColumnName(JdbcPersistentProperty property) {
return super.getColumnName(property) + "x";
}
};

@Test // DATAJDBC-113
public void simpleEntitiesGetProperlyExtracted() throws SQLException {
Expand All @@ -70,6 +79,36 @@ public void simpleEntitiesGetProperlyExtracted() throws SQLException {
.containsExactly(ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
}

@Test // DATAJDBC-181
public void namingStrategyGetsHonored() throws SQLException {

ResultSet rs = mockResultSet(asList("idx", "namex"), //
ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
rs.next();

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

assertThat(extracted) //
.isNotNull() //
.extracting(e -> e.id, e -> e.name) //
.containsExactly(ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
}

@Test // DATAJDBC-181
public void namingStrategyGetsHonoredForConstructor() throws SQLException {

ResultSet rs = mockResultSet(asList("idx", "namex"), //
ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
rs.next();

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

assertThat(extracted) //
.isNotNull() //
.extracting(e -> e.id, e -> e.name) //
.containsExactly(ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha");
}

@Test // DATAJDBC-113
public void simpleOneToOneGetsProperlyExtracted() throws SQLException {

Expand Down Expand Up @@ -131,8 +170,18 @@ public void listReferenceGetsLoadedWithAdditionalSelect() throws SQLException {
}

private <T> EntityRowMapper<T> createRowMapper(Class<T> type) {
return createRowMapper(type, new DefaultNamingStrategy());
}

private <T> EntityRowMapper<T> createRowMapper(Class<T> type, NamingStrategy namingStrategy) {

JdbcMappingContext context = new JdbcMappingContext( //
namingStrategy, //
mock(NamedParameterJdbcOperations.class), //
__ -> {
} //
);

JdbcMappingContext context = new JdbcMappingContext(mock(NamedParameterJdbcOperations.class));
DataAccessStrategy accessStrategy = mock(DataAccessStrategy.class);

// the ID of the entity is used to determine what kind of ResultSet is needed for subsequent selects.
Expand Down Expand Up @@ -240,7 +289,12 @@ private boolean isBeforeFirst() {
}

private Object getObject(String column) {
return values.get(index).get(column);

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));

return rowMap.get(column);
}

private boolean next() {
Expand All @@ -251,14 +305,20 @@ private boolean next() {
}

@RequiredArgsConstructor
static class TrivialImmutable {

@Id
private final Long id;
private final String name;
}

static class Trivial {

@Id
Long id;
String name;
}

@RequiredArgsConstructor
static class OneToOne {

@Id
Expand All @@ -267,7 +327,6 @@ static class OneToOne {
Trivial child;
}

@RequiredArgsConstructor
static class OneToSet {

@Id
Expand All @@ -276,7 +335,6 @@ static class OneToSet {
Set<Trivial> children;
}

@RequiredArgsConstructor
static class OneToMap {

@Id
Expand All @@ -285,7 +343,6 @@ static class OneToMap {
Map<String, Trivial> children;
}

@RequiredArgsConstructor
static class OneToList {

@Id
Expand Down