Skip to content

Commit 06c2a3a

Browse files
mp911deschauder
authored andcommitted
#22 - Polishing.
Add author tag. Add unit test for EntityRowMapper. Original pull request: #31.
1 parent f325f45 commit 06c2a3a

File tree

2 files changed

+96
-13
lines changed

2 files changed

+96
-13
lines changed

src/main/java/org/springframework/data/r2dbc/function/convert/EntityRowMapper.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.sql.ResultSet;
2424
import java.util.function.BiFunction;
2525

26-
import org.springframework.core.convert.ConversionService;
2726
import org.springframework.data.mapping.MappingException;
2827
import org.springframework.data.mapping.PersistentProperty;
2928
import org.springframework.data.mapping.PersistentPropertyAccessor;
@@ -39,7 +38,7 @@
3938
* Maps a {@link io.r2dbc.spi.Row} to an entity of type {@code T}, including entities referenced.
4039
*
4140
* @author Mark Paluch
42-
* @since 1.0
41+
* @author Ryland Degnan
4342
*/
4443
public class EntityRowMapper<T> implements BiFunction<Row, RowMetadata, T> {
4544

@@ -52,13 +51,17 @@ public EntityRowMapper(RelationalPersistentEntity<T> entity, RelationalConverter
5251
this.converter = converter;
5352
}
5453

54+
/*
55+
* (non-Javadoc)
56+
* @see java.util.function.BiFunction#apply(java.lang.Object, java.lang.Object)
57+
*/
5558
@Override
5659
public T apply(Row row, RowMetadata metadata) {
5760

5861
T result = createInstance(row, "", entity);
5962

60-
ConvertingPropertyAccessor propertyAccessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(result),
61-
converter.getConversionService());
63+
ConvertingPropertyAccessor<T> propertyAccessor = new ConvertingPropertyAccessor<>(
64+
entity.getPropertyAccessor(result), converter.getConversionService());
6265

6366
for (RelationalPersistentProperty property : entity) {
6467

@@ -93,7 +96,7 @@ private Object readFrom(Row row, RelationalPersistentProperty property, String p
9396
return readEntityFrom(row, property);
9497
}
9598

96-
return row.get(prefix + property.getColumnName());
99+
return converter.readValue(row.get(prefix + property.getColumnName()), property.getTypeInformation());
97100

98101
} catch (Exception o_O) {
99102
throw new MappingException(String.format("Could not read property %s from result set!", property), o_O);
@@ -104,7 +107,6 @@ private <S> S readEntityFrom(Row row, PersistentProperty<?> property) {
104107

105108
String prefix = property.getName() + "_";
106109

107-
@SuppressWarnings("unchecked")
108110
RelationalPersistentEntity<S> entity = (RelationalPersistentEntity<S>) converter.getMappingContext()
109111
.getRequiredPersistentEntity(property.getActualType());
110112

@@ -114,8 +116,8 @@ private <S> S readEntityFrom(Row row, PersistentProperty<?> property) {
114116

115117
S instance = createInstance(row, prefix, entity);
116118

117-
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(instance);
118-
ConvertingPropertyAccessor propertyAccessor = new ConvertingPropertyAccessor(accessor,
119+
PersistentPropertyAccessor<S> accessor = entity.getPropertyAccessor(instance);
120+
ConvertingPropertyAccessor<S> propertyAccessor = new ConvertingPropertyAccessor<>(accessor,
119121
converter.getConversionService());
120122

121123
for (RelationalPersistentProperty p : entity) {
@@ -129,8 +131,7 @@ private <S> S readEntityFrom(Row row, PersistentProperty<?> property) {
129131

130132
private <S> S createInstance(Row row, String prefix, RelationalPersistentEntity<S> entity) {
131133

132-
RowParameterValueProvider rowParameterValueProvider = new RowParameterValueProvider(row, entity,
133-
converter.getConversionService(), prefix);
134+
RowParameterValueProvider rowParameterValueProvider = new RowParameterValueProvider(row, entity, converter, prefix);
134135

135136
return converter.createInstance(entity, rowParameterValueProvider::getParameterValue);
136137
}
@@ -140,7 +141,7 @@ private static class RowParameterValueProvider implements ParameterValueProvider
140141

141142
private final @NonNull Row resultSet;
142143
private final @NonNull RelationalPersistentEntity<?> entity;
143-
private final @NonNull ConversionService conversionService;
144+
private final @NonNull RelationalConverter converter;
144145
private final @NonNull String prefix;
145146

146147
/*
@@ -151,10 +152,13 @@ private static class RowParameterValueProvider implements ParameterValueProvider
151152
@Nullable
152153
public <T> T getParameterValue(Parameter<T, RelationalPersistentProperty> parameter) {
153154

154-
String column = prefix + entity.getRequiredPersistentProperty(parameter.getName()).getColumnName();
155+
RelationalPersistentProperty property = entity.getRequiredPersistentProperty(parameter.getName());
156+
String column = prefix + property.getColumnName();
155157

156158
try {
157-
return conversionService.convert(resultSet.get(column), parameter.getType().getType());
159+
160+
Object value = converter.readValue(resultSet.get(column), property.getTypeInformation());
161+
return converter.getConversionService().convert(value, parameter.getType().getType());
158162
} catch (Exception o_O) {
159163
throw new MappingException(String.format("Couldn't read column %s from Row.", column), o_O);
160164
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package org.springframework.data.r2dbc.function.convert;
2+
3+
import static org.assertj.core.api.Assertions.*;
4+
import static org.mockito.Mockito.*;
5+
6+
import io.r2dbc.spi.Row;
7+
import io.r2dbc.spi.RowMetadata;
8+
import lombok.RequiredArgsConstructor;
9+
10+
import org.junit.Test;
11+
import org.junit.runner.RunWith;
12+
import org.mockito.junit.MockitoJUnitRunner;
13+
import org.springframework.data.r2dbc.dialect.PostgresDialect;
14+
import org.springframework.data.r2dbc.function.DefaultReactiveDataAccessStrategy;
15+
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
16+
17+
/**
18+
* Unit tests for {@link EntityRowMapper}.
19+
*
20+
* @author Mark Paluch
21+
*/
22+
@RunWith(MockitoJUnitRunner.class)
23+
public class EntityRowMapperUnitTests {
24+
25+
DefaultReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE);
26+
27+
Row rowMock = mock(Row.class);
28+
RowMetadata metadata = mock(RowMetadata.class);
29+
30+
@Test // gh-22
31+
public void shouldMapSimpleEntity() {
32+
33+
EntityRowMapper<SimpleEntity> mapper = getRowMapper(SimpleEntity.class);
34+
when(rowMock.get("id")).thenReturn("foo");
35+
36+
SimpleEntity result = mapper.apply(rowMock, metadata);
37+
assertThat(result.id).isEqualTo("foo");
38+
}
39+
40+
@Test // gh-22
41+
public void shouldMapSimpleEntityWithConstructorCreation() {
42+
43+
EntityRowMapper<SimpleEntityConstructorCreation> mapper = getRowMapper(SimpleEntityConstructorCreation.class);
44+
when(rowMock.get("id")).thenReturn("foo");
45+
46+
SimpleEntityConstructorCreation result = mapper.apply(rowMock, metadata);
47+
assertThat(result.id).isEqualTo("foo");
48+
}
49+
50+
@Test // gh-22
51+
public void shouldApplyConversionWithConstructorCreation() {
52+
53+
EntityRowMapper<ConversionWithConstructorCreation> mapper = getRowMapper(ConversionWithConstructorCreation.class);
54+
when(rowMock.get("id")).thenReturn((byte) 0x24);
55+
56+
ConversionWithConstructorCreation result = mapper.apply(rowMock, metadata);
57+
assertThat(result.id).isEqualTo(36L);
58+
}
59+
60+
private <T> EntityRowMapper<T> getRowMapper(Class<T> type) {
61+
RelationalPersistentEntity<T> entity = (RelationalPersistentEntity<T>) strategy.getMappingContext()
62+
.getRequiredPersistentEntity(type);
63+
return new EntityRowMapper<>(entity, strategy.getRelationalConverter());
64+
}
65+
66+
static class SimpleEntity {
67+
String id;
68+
}
69+
70+
@RequiredArgsConstructor
71+
static class SimpleEntityConstructorCreation {
72+
final String id;
73+
}
74+
75+
@RequiredArgsConstructor
76+
static class ConversionWithConstructorCreation {
77+
final long id;
78+
}
79+
}

0 commit comments

Comments
 (0)