Skip to content

Commit b4b6625

Browse files
schaudergregturn
authored andcommitted
DATAJDBC-207 - Default NamingStrategy is now Snake Case.
Moved the implementation from the DelimiterNamingStrategy into the NamingStrategy. Dropped the support for different separators, since there is no good way to support it in the default implementations of an interface. A getSeparator() method would bleed into the public API. Also the added value of that flexibility seems limited. During migration of the various test it became obvious that SqlGeneratorUnitTests was broken since test failures happend on a worker thread not on the main test thread. This is fixed as well with this commit.
1 parent 0460f2f commit b4b6625

File tree

44 files changed

+183
-213
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+183
-213
lines changed

src/main/java/org/springframework/data/jdbc/core/mapping/DelimiterNamingStrategy.java

Lines changed: 0 additions & 71 deletions
This file was deleted.

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

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@
1515
*/
1616
package org.springframework.data.jdbc.core.mapping;
1717

18+
import org.springframework.data.util.ParsingUtils;
19+
import org.springframework.util.Assert;
20+
1821
/**
1922
* Interface and default implementation of a naming strategy. Defaults to no schema, table name based on {@link Class}
20-
* and column name based on {@link JdbcPersistentProperty}.
23+
* and column name based on {@link JdbcPersistentProperty} with name parts of both separated by '_'.
2124
* <p>
2225
* NOTE: Can also be used as an adapter. Create a lambda or an anonymous subclass and override any settings to implement
2326
* a different strategy on the fly.
2427
*
2528
* @author Greg Turnquist
2629
* @author Michael Simons
2730
* @author Kazuki Shimizu
31+
* @author Jens Schauder
2832
* @author Oliver Gierke
2933
* @since 1.0
3034
*/
@@ -47,17 +51,24 @@ default String getSchema() {
4751
}
4852

4953
/**
50-
* Defaults to returning the given type's simple name.
54+
* The name of the table to be used for persisting entities having the type passed as an argument. The default
55+
* implementation takes the {@code type.getSimpleName()} and separates camel case parts with '_'.
5156
*/
5257
default String getTableName(Class<?> type) {
53-
return type.getSimpleName();
58+
59+
Assert.notNull(type, "Type must not be null.");
60+
61+
return ParsingUtils.reconcatenateCamelCase(type.getSimpleName(), "_");
5462
}
5563

5664
/**
57-
* Defaults to return the given {@link JdbcPersistentProperty}'s name;
65+
* Defaults to return the given {@link JdbcPersistentProperty}'s name with the parts of a camel case name separated by '_';
5866
*/
5967
default String getColumnName(JdbcPersistentProperty property) {
60-
return property.getName();
68+
69+
Assert.notNull(property, "Property must not be null.");
70+
71+
return ParsingUtils.reconcatenateCamelCase(property.getName(), "_");
6172
}
6273

6374
default String getQualifiedTableName(Class<?> type) {
@@ -71,6 +82,9 @@ default String getQualifiedTableName(Class<?> type) {
7182
* @return a column name. Must not be {@code null}.
7283
*/
7384
default String getReverseColumnName(JdbcPersistentProperty property) {
85+
86+
Assert.notNull(property,"Property must not be null.");
87+
7488
return property.getOwner().getTableName();
7589
}
7690

@@ -81,6 +95,9 @@ default String getReverseColumnName(JdbcPersistentProperty property) {
8195
* @return name of the key column. Must not be {@code null}.
8296
*/
8397
default String getKeyColumn(JdbcPersistentProperty property) {
98+
99+
Assert.notNull(property, "Property must not be null.");
100+
84101
return getReverseColumnName(property) + "_key";
85102
}
86103
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void additionalParameterForIdDoesNotLeadToDuplicateParameters() {
5757

5858
accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, additionalParameters);
5959

60-
verify(jdbcOperations).update(eq("INSERT INTO DummyEntity (id) VALUES (:id)"), paramSourceCaptor.capture(),
60+
verify(jdbcOperations).update(eq("INSERT INTO dummy_entity (id) VALUES (:id)"), paramSourceCaptor.capture(),
6161
any(KeyHolder.class));
6262
}
6363

@@ -73,8 +73,8 @@ public void additionalParametersGetAddedToStatement() {
7373
verify(jdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class));
7474

7575
assertThat(sqlCaptor.getValue()) //
76-
.containsSequence("INSERT INTO DummyEntity (", "id", ") VALUES (", ":id", ")") //
77-
.containsSequence("INSERT INTO DummyEntity (", "reference", ") VALUES (", ":reference", ")");
76+
.containsSequence("INSERT INTO dummy_entity (", "id", ") VALUES (", ":id", ")") //
77+
.containsSequence("INSERT INTO dummy_entity (", "reference", ") VALUES (", ":reference", ")");
7878
assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(ORIGINAL_ID);
7979
}
8080

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

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.util.concurrent.CountDownLatch;
2121
import java.util.concurrent.TimeUnit;
22+
import java.util.concurrent.atomic.AtomicReference;
2223
import java.util.function.Consumer;
2324

2425
import org.assertj.core.api.SoftAssertions;
@@ -63,11 +64,11 @@ public void findOne() {
6364
SoftAssertions softAssertions = new SoftAssertions();
6465
softAssertions.assertThat(sql) //
6566
.startsWith("SELECT") //
66-
.contains(user + ".DummyEntity.id AS id,") //
67-
.contains(user + ".DummyEntity.name AS name,") //
67+
.contains(user + ".dummy_entity.id AS id,") //
68+
.contains(user + ".dummy_entity.name AS name,") //
6869
.contains("ref.l1id AS ref_l1id") //
6970
.contains("ref.content AS ref_content") //
70-
.contains("FROM " + user + ".DummyEntity");
71+
.contains("FROM " + user + ".dummy_entity");
7172
softAssertions.assertAll();
7273
});
7374
}
@@ -81,7 +82,7 @@ public void cascadingDeleteFirstLevel() {
8182

8283
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref", DummyEntity.class));
8384

84-
assertThat(sql).isEqualTo("DELETE FROM " + user + ".ReferencedEntity WHERE " + user + ".DummyEntity = :rootId");
85+
assertThat(sql).isEqualTo("DELETE FROM " + user + ".referenced_entity WHERE " + user + ".dummy_entity = :rootId");
8586
});
8687
}
8788

@@ -94,9 +95,11 @@ public void cascadingDeleteAllSecondLevel() {
9495

9596
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class));
9697

97-
assertThat(sql)
98-
.isEqualTo("DELETE FROM " + user + ".SecondLevelReferencedEntity " + "WHERE " + user + ".ReferencedEntity IN "
99-
+ "(SELECT l1id FROM " + user + ".ReferencedEntity " + "WHERE " + user + ".DummyEntity = :rootId)");
98+
assertThat(sql).isEqualTo(
99+
"DELETE FROM " + user + ".second_level_referenced_entity " +
100+
"WHERE " + user + ".referenced_entity IN " +
101+
"(SELECT l1id FROM " + user + ".referenced_entity " +
102+
"WHERE " + user + ".dummy_entity = :rootId)");
100103
});
101104
}
102105

@@ -109,7 +112,7 @@ public void deleteAll() {
109112

110113
String sql = sqlGenerator.createDeleteAllSql(null);
111114

112-
assertThat(sql).isEqualTo("DELETE FROM " + user + ".DummyEntity");
115+
assertThat(sql).isEqualTo("DELETE FROM " + user + ".dummy_entity");
113116
});
114117
}
115118

@@ -122,7 +125,8 @@ public void cascadingDeleteAllFirstLevel() {
122125

123126
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref", DummyEntity.class));
124127

125-
assertThat(sql).isEqualTo("DELETE FROM " + user + ".ReferencedEntity WHERE " + user + ".DummyEntity IS NOT NULL");
128+
assertThat(sql).isEqualTo(
129+
"DELETE FROM " + user + ".referenced_entity WHERE " + user + ".dummy_entity IS NOT NULL");
126130
});
127131
}
128132

@@ -135,9 +139,11 @@ public void cascadingDeleteSecondLevel() {
135139

136140
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class));
137141

138-
assertThat(sql)
139-
.isEqualTo("DELETE FROM " + user + ".SecondLevelReferencedEntity " + "WHERE " + user + ".ReferencedEntity IN "
140-
+ "(SELECT l1id FROM " + user + ".ReferencedEntity " + "WHERE " + user + ".DummyEntity IS NOT NULL)");
142+
assertThat(sql).isEqualTo(
143+
"DELETE FROM " + user + ".second_level_referenced_entity " +
144+
"WHERE " + user + ".referenced_entity IN " +
145+
"(SELECT l1id FROM " + user + ".referenced_entity " +
146+
"WHERE " + user + ".dummy_entity IS NOT NULL)");
141147
});
142148
}
143149

@@ -146,30 +152,45 @@ public void cascadingDeleteSecondLevel() {
146152
*/
147153
private void testAgainstMultipleUsers(Consumer<String> testAssertions) {
148154

155+
AtomicReference<Error> exception = new AtomicReference<>();
149156
CountDownLatch latch = new CountDownLatch(2);
150157

151-
threadedTest("User1", latch, testAssertions);
152-
threadedTest("User2", latch, testAssertions);
158+
threadedTest("User1", latch, testAssertions, exception);
159+
threadedTest("User2", latch, testAssertions, exception);
153160

154161
try {
155-
latch.await(10L, TimeUnit.SECONDS);
162+
if (!latch.await(10L, TimeUnit.SECONDS)){
163+
fail("Test failed due to a time out.");
164+
}
156165
} catch (InterruptedException e) {
157166
throw new RuntimeException(e);
158167
}
168+
169+
Error ex = exception.get();
170+
if (ex != null) {
171+
throw ex;
172+
}
159173
}
160174

161175
/**
162176
* Inside a {@link Runnable}, fetch the {@link ThreadLocal}-based username and execute the provided set of assertions.
163177
* Then signal through the provided {@link CountDownLatch}.
164178
*/
165-
private void threadedTest(String user, CountDownLatch latch, Consumer<String> testAssertions) {
179+
private void threadedTest(String user, CountDownLatch latch, Consumer<String> testAssertions, AtomicReference<Error> exception) {
166180

167181
new Thread(() -> {
168-
userHandler.set(user);
169182

170-
testAssertions.accept(user);
183+
try {
184+
185+
userHandler.set(user);
186+
testAssertions.accept(user);
187+
188+
} catch (Error ex) {
189+
exception.compareAndSet(null, ex);
190+
} finally {
191+
latch.countDown();
192+
}
171193

172-
latch.countDown();
173194
}).start();
174195
}
175196

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ public void findOne() {
5757
SoftAssertions softAssertions = new SoftAssertions();
5858
softAssertions.assertThat(sql) //
5959
.startsWith("SELECT") //
60-
.contains("DummyEntity.x_id AS x_id,") //
61-
.contains("DummyEntity.x_name AS x_name,") //
60+
.contains("dummy_entity.x_id AS x_id,") //
61+
.contains("dummy_entity.x_name AS x_name,") //
6262
.contains("ref.x_l1id AS ref_x_l1id") //
63-
.contains("ref.x_content AS ref_x_content").contains(" FROM DummyEntity") //
63+
.contains("ref.x_content AS ref_x_content").contains(" FROM dummy_entity") //
6464
// 1-N relationships do not get loaded via join
6565
.doesNotContain("Element AS elements");
6666
softAssertions.assertAll();
@@ -71,7 +71,7 @@ public void cascadingDeleteFirstLevel() {
7171

7272
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref", DummyEntity.class));
7373

74-
assertThat(sql).isEqualTo("DELETE FROM ReferencedEntity WHERE DummyEntity = :rootId");
74+
assertThat(sql).isEqualTo("DELETE FROM referenced_entity WHERE dummy_entity = :rootId");
7575
}
7676

7777
@Test // DATAJDBC-112
@@ -80,23 +80,23 @@ public void cascadingDeleteAllSecondLevel() {
8080
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class));
8181

8282
assertThat(sql).isEqualTo(
83-
"DELETE FROM SecondLevelReferencedEntity WHERE ReferencedEntity IN (SELECT x_l1id FROM ReferencedEntity WHERE DummyEntity = :rootId)");
83+
"DELETE FROM second_level_referenced_entity WHERE referenced_entity IN (SELECT x_l1id FROM referenced_entity WHERE dummy_entity = :rootId)");
8484
}
8585

8686
@Test // DATAJDBC-112
8787
public void deleteAll() {
8888

8989
String sql = sqlGenerator.createDeleteAllSql(null);
9090

91-
assertThat(sql).isEqualTo("DELETE FROM DummyEntity");
91+
assertThat(sql).isEqualTo("DELETE FROM dummy_entity");
9292
}
9393

9494
@Test // DATAJDBC-112
9595
public void cascadingDeleteAllFirstLevel() {
9696

9797
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref", DummyEntity.class));
9898

99-
assertThat(sql).isEqualTo("DELETE FROM ReferencedEntity WHERE DummyEntity IS NOT NULL");
99+
assertThat(sql).isEqualTo("DELETE FROM referenced_entity WHERE dummy_entity IS NOT NULL");
100100
}
101101

102102
@Test // DATAJDBC-112
@@ -105,7 +105,7 @@ public void cascadingDeleteSecondLevel() {
105105
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class));
106106

107107
assertThat(sql).isEqualTo(
108-
"DELETE FROM SecondLevelReferencedEntity WHERE ReferencedEntity IN (SELECT x_l1id FROM ReferencedEntity WHERE DummyEntity IS NOT NULL)");
108+
"DELETE FROM second_level_referenced_entity WHERE referenced_entity IN (SELECT x_l1id FROM referenced_entity WHERE dummy_entity IS NOT NULL)");
109109
}
110110

111111
@Test // DATAJDBC-131
@@ -114,9 +114,9 @@ public void findAllByProperty() {
114114
// this would get called when DummyEntity is the element type of a Set
115115
String sql = sqlGenerator.getFindAllByProperty("back-ref", null, false);
116116

117-
assertThat(sql).isEqualTo("SELECT DummyEntity.x_id AS x_id, DummyEntity.x_name AS x_name, "
117+
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, "
118118
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further "
119-
+ "FROM DummyEntity LEFT OUTER JOIN ReferencedEntity AS ref ON ref.DummyEntity = DummyEntity.x_id "
119+
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id "
120120
+ "WHERE back-ref = :back-ref");
121121
}
122122

@@ -126,10 +126,10 @@ public void findAllByPropertyWithKey() {
126126
// this would get called when DummyEntity is th element type of a Map
127127
String sql = sqlGenerator.getFindAllByProperty("back-ref", "key-column", false);
128128

129-
assertThat(sql).isEqualTo("SELECT DummyEntity.x_id AS x_id, DummyEntity.x_name AS x_name, "
129+
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, "
130130
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further, "
131-
+ "DummyEntity.key-column AS key-column "
132-
+ "FROM DummyEntity LEFT OUTER JOIN ReferencedEntity AS ref ON ref.DummyEntity = DummyEntity.x_id "
131+
+ "dummy_entity.key-column AS key-column "
132+
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id "
133133
+ "WHERE back-ref = :back-ref");
134134
}
135135

@@ -144,10 +144,10 @@ public void findAllByPropertyWithKeyOrdered() {
144144
// this would get called when DummyEntity is th element type of a Map
145145
String sql = sqlGenerator.getFindAllByProperty("back-ref", "key-column", true);
146146

147-
assertThat(sql).isEqualTo("SELECT DummyEntity.x_id AS x_id, DummyEntity.x_name AS x_name, "
147+
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, "
148148
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further, "
149-
+ "DummyEntity.key-column AS key-column "
150-
+ "FROM DummyEntity LEFT OUTER JOIN ReferencedEntity AS ref ON ref.DummyEntity = DummyEntity.x_id "
149+
+ "dummy_entity.key-column AS key-column "
150+
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id "
151151
+ "WHERE back-ref = :back-ref " + "ORDER BY key-column");
152152
}
153153

0 commit comments

Comments
 (0)