Skip to content

Commit fbc271a

Browse files
committed
DATAJDBC-106 - Polishing.
Moved annotation processing of @table and @column into metamodel classes so that the NamingStrategy is only responsible for generic fallbacks. Allow @column to be used as meta-annotation.
1 parent eab63d8 commit fbc271a

11 files changed

+120
-85
lines changed

src/main/java/org/springframework/data/jdbc/mapping/model/BasicJdbcPersistentProperty.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,23 @@
1515
*/
1616
package org.springframework.data.jdbc.mapping.model;
1717

18+
import java.time.ZonedDateTime;
19+
import java.time.temporal.Temporal;
20+
import java.util.Date;
21+
import java.util.LinkedHashMap;
22+
import java.util.Map;
23+
import java.util.Optional;
24+
import java.util.Set;
25+
1826
import org.springframework.data.mapping.Association;
1927
import org.springframework.data.mapping.PersistentEntity;
2028
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
2129
import org.springframework.data.mapping.model.Property;
2230
import org.springframework.data.mapping.model.SimpleTypeHolder;
31+
import org.springframework.data.util.Lazy;
2332
import org.springframework.util.Assert;
2433
import org.springframework.util.ClassUtils;
2534

26-
import java.time.ZonedDateTime;
27-
import java.time.temporal.Temporal;
28-
import java.util.Date;
29-
import java.util.LinkedHashMap;
30-
import java.util.Map;
31-
import java.util.Set;
32-
3335
/**
3436
* Meta data about a property to be used by repository implementations.
3537
*
@@ -43,6 +45,8 @@ public class BasicJdbcPersistentProperty extends AnnotationBasedPersistentProper
4345
private static final Map<Class<?>, Class<?>> javaToDbType = new LinkedHashMap<>();
4446
private final JdbcMappingContext context;
4547

48+
private final Lazy<Optional<String>> columnName;
49+
4650
static {
4751
javaToDbType.put(Enum.class, String.class);
4852
javaToDbType.put(ZonedDateTime.class, String.class);
@@ -52,19 +56,20 @@ public class BasicJdbcPersistentProperty extends AnnotationBasedPersistentProper
5256
/**
5357
* Creates a new {@link AnnotationBasedPersistentProperty}.
5458
*
55-
* @param property must not be {@literal null}.
56-
* @param owner must not be {@literal null}.
59+
* @param property must not be {@literal null}.
60+
* @param owner must not be {@literal null}.
5761
* @param simpleTypeHolder must not be {@literal null}.
58-
* @param context must not be {@literal null}
62+
* @param context must not be {@literal null}
5963
*/
6064
public BasicJdbcPersistentProperty(Property property, PersistentEntity<?, JdbcPersistentProperty> owner,
61-
SimpleTypeHolder simpleTypeHolder, JdbcMappingContext context) {
65+
SimpleTypeHolder simpleTypeHolder, JdbcMappingContext context) {
6266

6367
super(property, owner, simpleTypeHolder);
6468

6569
Assert.notNull(context, "context must not be null.");
6670

6771
this.context = context;
72+
this.columnName = Lazy.of(() -> Optional.ofNullable(findAnnotation(Column.class)).map(Column::value));
6873
}
6974

7075
/*
@@ -81,7 +86,7 @@ protected Association<JdbcPersistentProperty> createAssociation() {
8186
* @see org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty#getColumnName()
8287
*/
8388
public String getColumnName() {
84-
return context.getNamingStrategy().getColumnName(this);
89+
return columnName.get().orElseGet(() -> context.getNamingStrategy().getColumnName(this));
8590
}
8691

8792
/**

src/main/java/org/springframework/data/jdbc/mapping/model/Column.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@
2828
* @since 1.0
2929
*/
3030
@Retention(RetentionPolicy.RUNTIME)
31-
@Target({ ElementType.FIELD, ElementType.METHOD })
31+
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
3232
@Documented
3333
public @interface Column {
3434

3535
/**
3636
* The mapping column name.
3737
*/
3838
String value();
39-
4039
}

src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntity.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616
package org.springframework.data.jdbc.mapping.model;
1717

18-
import org.springframework.data.mapping.PersistentEntity;
1918
import org.springframework.data.mapping.model.MutablePersistentEntity;
2019

2120
/**

src/main/java/org/springframework/data/jdbc/mapping/model/JdbcPersistentEntityImpl.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
*/
1616
package org.springframework.data.jdbc.mapping.model;
1717

18-
import lombok.Getter;
18+
import java.util.Optional;
1919

2020
import org.springframework.data.mapping.model.BasicPersistentEntity;
21+
import org.springframework.data.util.Lazy;
2122
import org.springframework.data.util.TypeInformation;
2223

2324
/**
@@ -31,7 +32,7 @@ class JdbcPersistentEntityImpl<T> extends BasicPersistentEntity<T, JdbcPersisten
3132
implements JdbcPersistentEntity<T> {
3233

3334
private final NamingStrategy namingStrategy;
34-
private final @Getter String tableName;
35+
private final Lazy<Optional<String>> tableName;
3536

3637
/**
3738
* Creates a new {@link JdbcPersistentEntityImpl} for the given {@link TypeInformation}.
@@ -43,7 +44,16 @@ class JdbcPersistentEntityImpl<T> extends BasicPersistentEntity<T, JdbcPersisten
4344
super(information);
4445

4546
this.namingStrategy = namingStrategy;
46-
this.tableName = this.namingStrategy.getQualifiedTableName(getType());
47+
this.tableName = Lazy.of(() -> Optional.ofNullable(findAnnotation(Table.class)).map(Table::value));
48+
}
49+
50+
/*
51+
* (non-Javadoc)
52+
* @see org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity#getTableName()
53+
*/
54+
@Override
55+
public String getTableName() {
56+
return tableName.get().orElseGet(() -> namingStrategy.getQualifiedTableName(getType()));
4757
}
4858

4959
/*
@@ -55,8 +65,12 @@ public String getIdColumn() {
5565
return this.namingStrategy.getColumnName(getRequiredIdProperty());
5666
}
5767

68+
/*
69+
* (non-Javadoc)
70+
* @see java.lang.Object#toString()
71+
*/
5872
@Override
5973
public String toString() {
60-
return String.format("JdbcpersistentEntityImpl<%s>", getType());
74+
return String.format("JdbcPersistentEntityImpl<%s>", getType());
6175
}
6276
}

src/main/java/org/springframework/data/jdbc/mapping/model/NamingStrategy.java

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
*/
1616
package org.springframework.data.jdbc.mapping.model;
1717

18-
import java.util.Optional;
19-
20-
import org.springframework.core.annotation.AnnotatedElementUtils;
21-
2218
/**
2319
* Interface and default implementation of a naming strategy. Defaults to no schema, table name based on {@link Class}
2420
* and column name based on {@link JdbcPersistentProperty}.
@@ -29,7 +25,7 @@
2925
* @author Greg Turnquist
3026
* @author Michael Simons
3127
* @author Kazuki Shimizu
32-
*
28+
* @author Oliver Gierke
3329
* @since 1.0
3430
*/
3531
public interface NamingStrategy {
@@ -51,25 +47,17 @@ default String getSchema() {
5147
}
5248

5349
/**
54-
* Look up the {@link Class}'s simple name or {@link Table#value()}.
50+
* Defaults to returning the given type's simple name.
5551
*/
5652
default String getTableName(Class<?> type) {
57-
58-
Table table = AnnotatedElementUtils.findMergedAnnotation(type, Table.class);
59-
return Optional.ofNullable(table)//
60-
.map(Table::value)//
61-
.orElse(type.getSimpleName());
53+
return type.getSimpleName();
6254
}
6355

6456
/**
65-
* Look up the {@link JdbcPersistentProperty}'s name or {@link Column#value()}.
57+
* Defaults to return the given {@link JdbcPersistentProperty}'s name;
6658
*/
6759
default String getColumnName(JdbcPersistentProperty property) {
68-
69-
Column column = property.findAnnotation(Column.class);
70-
return Optional.ofNullable(column)//
71-
.map(Column::value)//
72-
.orElse(property.getName());
60+
return property.getName();
7361
}
7462

7563
default String getQualifiedTableName(Class<?> type) {
@@ -95,5 +83,4 @@ default String getReverseColumnName(JdbcPersistentProperty property) {
9583
default String getKeyColumn(JdbcPersistentProperty property) {
9684
return getReverseColumnName(property) + "_key";
9785
}
98-
9986
}

src/main/java/org/springframework/data/jdbc/mapping/model/Table.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,4 @@
3838
* The mapping table name.
3939
*/
4040
String value();
41-
4241
}

src/test/java/org/springframework/data/jdbc/core/SqlGeneratorContextBasedNamingStrategyUnitTests.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,27 +191,23 @@ private SqlGenerator configureSqlGenerator(NamingStrategy namingStrategy) {
191191
return new SqlGenerator(context, persistentEntity, new SqlGeneratorSource(context));
192192
}
193193

194-
@SuppressWarnings("unused")
195194
static class DummyEntity {
196195

197196
@Id Long id;
198197
String name;
199198
ReferencedEntity ref;
200199
}
201200

202-
@SuppressWarnings("unused")
203201
static class ReferencedEntity {
204202

205203
@Id Long l1id;
206204
String content;
207205
SecondLevelReferencedEntity further;
208206
}
209207

210-
@SuppressWarnings("unused")
211208
static class SecondLevelReferencedEntity {
212209

213210
@Id Long l2id;
214211
String something;
215212
}
216-
217213
}

src/test/java/org/springframework/data/jdbc/mapping/model/BasicJdbcPersistentPropertyUnitTests.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@
3535
*/
3636
public class BasicJdbcPersistentPropertyUnitTests {
3737

38+
JdbcMappingContext context = new JdbcMappingContext(mock(NamedParameterJdbcOperations.class));
39+
3840
@Test // DATAJDBC-104
3941
public void enumGetsStoredAsString() {
4042

41-
JdbcPersistentEntity<?> persistentEntity = new JdbcMappingContext(mock(NamedParameterJdbcOperations.class))
42-
.getRequiredPersistentEntity(DummyEntity.class);
43+
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class);
4344

4445
persistentEntity.doWithProperties((PropertyHandler<JdbcPersistentProperty>) p -> {
4546
switch (p.getName()) {
@@ -53,10 +54,18 @@ public void enumGetsStoredAsString() {
5354
assertThat(p.getColumnType()).isEqualTo(String.class);
5455
break;
5556
default:
56-
fail("property with out assert: " + p.getName());
5757
}
5858
});
59+
}
60+
61+
@Test // DATAJDBC-106
62+
public void detectsAnnotatedColumnName() {
63+
64+
JdbcPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
5965

66+
assertThat(entity.getRequiredPersistentProperty("name").getColumnName()).isEqualTo("dummy_name");
67+
assertThat(entity.getRequiredPersistentProperty("localDateTime").getColumnName())
68+
.isEqualTo("dummy_last_updated_at");
6069
}
6170

6271
@Data
@@ -65,10 +74,18 @@ private static class DummyEntity {
6574
private final SomeEnum someEnum;
6675
private final LocalDateTime localDateTime;
6776
private final ZonedDateTime zonedDateTime;
77+
78+
// DATACMNS-106
79+
80+
private @Column("dummy_name") String name;
81+
82+
@Column("dummy_last_updated_at")
83+
public LocalDateTime getLocalDateTime() {
84+
return localDateTime;
85+
}
6886
}
6987

7088
private enum SomeEnum {
71-
@SuppressWarnings("unused")
72-
ALPHA
89+
ALPHA;
7390
}
7491
}

src/test/java/org/springframework/data/jdbc/mapping/model/JdbcMappingContextUnitTests.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void referencedEntitiesGetFound() {
4747
.containsExactly( //
4848
"one.two", //
4949
"one" //
50-
);
50+
);
5151
}
5252

5353
@Test // DATAJDBC-142
@@ -64,21 +64,20 @@ public void propertyPathDoesNotDependOnNamingStrategy() {
6464
.containsExactly( //
6565
"one.two", //
6666
"one" //
67-
);
67+
);
6868
}
6969

70-
private static class DummyEntity {
70+
static class DummyEntity {
7171

7272
String simpleProperty;
73-
7473
LevelOne one;
7574
}
7675

77-
private static class LevelOne {
76+
static class LevelOne {
7877
LevelTwo two;
7978
}
8079

81-
private static class LevelTwo {
80+
static class LevelTwo {
8281
String someValue;
8382
}
8483
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc.mapping.model;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
import static org.mockito.Mockito.*;
20+
21+
import org.junit.Test;
22+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
23+
24+
/**
25+
* Unit tests for {@link JdbcPersistentEntityImpl}.
26+
*
27+
* @author Oliver Gierke
28+
* @author Kazuki Shimizu
29+
*/
30+
public class JdbcPersistentEntityImplUnitTests {
31+
32+
JdbcMappingContext mappingContext = new JdbcMappingContext(mock(NamedParameterJdbcOperations.class));
33+
34+
@Test // DATAJDBC-106
35+
public void discoversAnnotatedTableName() {
36+
37+
JdbcPersistentEntity<?> entity = mappingContext.getPersistentEntity(DummySubEntity.class);
38+
39+
assertThat(entity.getTableName()).isEqualTo("dummy_sub_entity");
40+
}
41+
42+
@Table("dummy_sub_entity")
43+
static class DummySubEntity {}
44+
}

0 commit comments

Comments
 (0)