Skip to content

Commit 3329a2a

Browse files
committed
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 1c48a96 commit 3329a2a

File tree

42 files changed

+156
-204
lines changed

Some content is hidden

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

42 files changed

+156
-204
lines changed

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

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

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

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

18+
import org.springframework.data.util.ParsingUtils;
19+
1820
/**
1921
* 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}.
22+
* and column name based on {@link JdbcPersistentProperty} with name parts of both separated by '_'.
2123
* <p>
2224
* NOTE: Can also be used as an adapter. Create a lambda or an anonymous subclass and override any settings to implement
2325
* a different strategy on the fly.
2426
*
2527
* @author Greg Turnquist
2628
* @author Michael Simons
29+
* @author Kazuki Shimizu
30+
* @author Jens Schauder
2731
* @since 1.0
2832
*/
2933
public interface NamingStrategy {
@@ -45,17 +49,18 @@ default String getSchema() {
4549
}
4650

4751
/**
48-
* Look up the {@link Class}'s simple name.
52+
* The name of the table to be used for persisting entities having the type passed as an argument. The default
53+
* implementation takes the {@code type.getSimpleName()} and separates camel case parts with '_'.
4954
*/
5055
default String getTableName(Class<?> type) {
51-
return type.getSimpleName();
56+
return ParsingUtils.reconcatenateCamelCase(type.getSimpleName(), "_");
5257
}
5358

5459
/**
5560
* Look up the {@link JdbcPersistentProperty}'s name.
5661
*/
5762
default String getColumnName(JdbcPersistentProperty property) {
58-
return property.getName();
63+
return ParsingUtils.reconcatenateCamelCase(property.getName(), "_");
5964
}
6065

6166
default String getQualifiedTableName(Class<?> type) {

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

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

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

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

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

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

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

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import java.util.concurrent.CountDownLatch;
2222
import java.util.concurrent.TimeUnit;
23+
import java.util.concurrent.atomic.AtomicReference;
2324
import java.util.function.Consumer;
2425

2526
import org.assertj.core.api.SoftAssertions;
@@ -65,11 +66,11 @@ public void findOne() {
6566
SoftAssertions softAssertions = new SoftAssertions();
6667
softAssertions.assertThat(sql) //
6768
.startsWith("SELECT") //
68-
.contains(user + ".DummyEntity.id AS id,") //
69-
.contains(user + ".DummyEntity.name AS name,") //
69+
.contains(user + ".dummy_entity.id AS id,") //
70+
.contains(user + ".dummy_entity.name AS name,") //
7071
.contains("ref.l1id AS ref_l1id") //
7172
.contains("ref.content AS ref_content") //
72-
.contains("FROM " + user + ".DummyEntity");
73+
.contains("FROM " + user + ".dummy_entity");
7374
softAssertions.assertAll();
7475
});
7576
}
@@ -83,7 +84,7 @@ public void cascadingDeleteFirstLevel() {
8384

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

86-
assertThat(sql).isEqualTo("DELETE FROM " + user + ".ReferencedEntity WHERE " + user + ".DummyEntity = :rootId");
87+
assertThat(sql).isEqualTo("DELETE FROM " + user + ".referenced_entity WHERE " + user + ".dummy_entity = :rootId");
8788
});
8889
}
8990

@@ -97,10 +98,10 @@ public void cascadingDeleteAllSecondLevel() {
9798
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class));
9899

99100
assertThat(sql).isEqualTo(
100-
"DELETE FROM " + user + ".SecondLevelReferencedEntity " +
101-
"WHERE " + user + ".ReferencedEntity IN " +
102-
"(SELECT l1id FROM " + user + ".ReferencedEntity " +
103-
"WHERE " + user + ".DummyEntity = :rootId)");
101+
"DELETE FROM " + user + ".second_level_referenced_entity " +
102+
"WHERE " + user + ".referenced_entity IN " +
103+
"(SELECT l1id FROM " + user + ".referenced_entity " +
104+
"WHERE " + user + ".dummy_entity = :rootId)");
104105
});
105106
}
106107

@@ -113,7 +114,7 @@ public void deleteAll() {
113114

114115
String sql = sqlGenerator.createDeleteAllSql(null);
115116

116-
assertThat(sql).isEqualTo("DELETE FROM " + user + ".DummyEntity");
117+
assertThat(sql).isEqualTo("DELETE FROM " + user + ".dummy_entity");
117118
});
118119
}
119120

@@ -127,7 +128,7 @@ public void cascadingDeleteAllFirstLevel() {
127128
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref", DummyEntity.class));
128129

129130
assertThat(sql).isEqualTo(
130-
"DELETE FROM " + user + ".ReferencedEntity WHERE " + user + ".DummyEntity IS NOT NULL");
131+
"DELETE FROM " + user + ".referenced_entity WHERE " + user + ".dummy_entity IS NOT NULL");
131132
});
132133
}
133134

@@ -141,10 +142,10 @@ public void cascadingDeleteSecondLevel() {
141142
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class));
142143

143144
assertThat(sql).isEqualTo(
144-
"DELETE FROM " + user + ".SecondLevelReferencedEntity " +
145-
"WHERE " + user + ".ReferencedEntity IN " +
146-
"(SELECT l1id FROM " + user + ".ReferencedEntity " +
147-
"WHERE " + user + ".DummyEntity IS NOT NULL)");
145+
"DELETE FROM " + user + ".second_level_referenced_entity " +
146+
"WHERE " + user + ".referenced_entity IN " +
147+
"(SELECT l1id FROM " + user + ".referenced_entity " +
148+
"WHERE " + user + ".dummy_entity IS NOT NULL)");
148149
});
149150
}
150151

@@ -153,30 +154,45 @@ public void cascadingDeleteSecondLevel() {
153154
*/
154155
private void testAgainstMultipleUsers(Consumer<String> testAssertions) {
155156

157+
AtomicReference<Error> exception = new AtomicReference<>();
156158
CountDownLatch latch = new CountDownLatch(2);
157159

158-
threadedTest("User1", latch, testAssertions);
159-
threadedTest("User2", latch, testAssertions);
160+
threadedTest("User1", latch, testAssertions, exception);
161+
threadedTest("User2", latch, testAssertions, exception);
160162

161163
try {
162-
latch.await(10L, TimeUnit.SECONDS);
164+
if (!latch.await(10L, TimeUnit.SECONDS)){
165+
fail("Test failed due to a time out.");
166+
}
163167
} catch (InterruptedException e) {
164168
throw new RuntimeException(e);
165169
}
170+
171+
Error ex = exception.get();
172+
if (ex != null) {
173+
throw ex;
174+
}
166175
}
167176

168177
/**
169178
* Inside a {@link Runnable}, fetch the {@link ThreadLocal}-based username and execute the provided
170179
* set of assertions. Then signal through the provided {@link CountDownLatch}.
171180
*/
172-
private void threadedTest(String user, CountDownLatch latch, Consumer<String> testAssertions) {
181+
private void threadedTest(String user, CountDownLatch latch, Consumer<String> testAssertions, AtomicReference<Error> exception) {
173182

174183
new Thread(() -> {
175-
userHandler.set(user);
176184

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

179-
latch.countDown();
180196
}).start();
181197
}
182198

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ public void findOne() {
5959
SoftAssertions softAssertions = new SoftAssertions();
6060
softAssertions.assertThat(sql) //
6161
.startsWith("SELECT") //
62-
.contains("DummyEntity.x_id AS x_id,") //
63-
.contains("DummyEntity.x_name AS x_name,") //
62+
.contains("dummy_entity.x_id AS x_id,") //
63+
.contains("dummy_entity.x_name AS x_name,") //
6464
.contains("ref.x_l1id AS ref_x_l1id") //
65-
.contains("ref.x_content AS ref_x_content").contains(" FROM DummyEntity") //
65+
.contains("ref.x_content AS ref_x_content").contains(" FROM dummy_entity") //
6666
// 1-N relationships do not get loaded via join
6767
.doesNotContain("Element AS elements");
6868
softAssertions.assertAll();
@@ -73,7 +73,7 @@ public void cascadingDeleteFirstLevel() {
7373

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

76-
assertThat(sql).isEqualTo("DELETE FROM ReferencedEntity WHERE DummyEntity = :rootId");
76+
assertThat(sql).isEqualTo("DELETE FROM referenced_entity WHERE dummy_entity = :rootId");
7777
}
7878

7979
@Test // DATAJDBC-112
@@ -82,23 +82,23 @@ public void cascadingDeleteAllSecondLevel() {
8282
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class));
8383

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

8888
@Test // DATAJDBC-112
8989
public void deleteAll() {
9090

9191
String sql = sqlGenerator.createDeleteAllSql(null);
9292

93-
assertThat(sql).isEqualTo("DELETE FROM DummyEntity");
93+
assertThat(sql).isEqualTo("DELETE FROM dummy_entity");
9494
}
9595

9696
@Test // DATAJDBC-112
9797
public void cascadingDeleteAllFirstLevel() {
9898

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

101-
assertThat(sql).isEqualTo("DELETE FROM ReferencedEntity WHERE DummyEntity IS NOT NULL");
101+
assertThat(sql).isEqualTo("DELETE FROM referenced_entity WHERE dummy_entity IS NOT NULL");
102102
}
103103

104104
@Test // DATAJDBC-112
@@ -107,7 +107,7 @@ public void cascadingDeleteSecondLevel() {
107107
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class));
108108

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

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

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

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

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

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

149-
assertThat(sql).isEqualTo("SELECT DummyEntity.x_id AS x_id, DummyEntity.x_name AS x_name, "
149+
assertThat(sql).isEqualTo("SELECT dummy_entity.x_id AS x_id, dummy_entity.x_name AS x_name, "
150150
+ "ref.x_l1id AS ref_x_l1id, ref.x_content AS ref_x_content, ref.x_further AS ref_x_further, "
151-
+ "DummyEntity.key-column AS key-column "
152-
+ "FROM DummyEntity LEFT OUTER JOIN ReferencedEntity AS ref ON ref.DummyEntity = DummyEntity.x_id "
151+
+ "dummy_entity.key-column AS key-column "
152+
+ "FROM dummy_entity LEFT OUTER JOIN referenced_entity AS ref ON ref.dummy_entity = dummy_entity.x_id "
153153
+ "WHERE back-ref = :back-ref "
154154
+ "ORDER BY key-column"
155155
);

src/test/java/org/springframework/data/jdbc/core/conversion/JdbcEntityWriterUnitTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,11 @@ private CascadingReferenceMiddleElement createMiddleElement(Element first, Eleme
327327
}
328328

329329
private Object getMapKey(DbAction a) {
330-
return a.getAdditionalValues().get("MapContainer_key");
330+
return a.getAdditionalValues().get("map_container_key");
331331
}
332332

333333
private Object getListKey(DbAction a) {
334-
return a.getAdditionalValues().get("ListContainer_key");
334+
return a.getAdditionalValues().get("list_container_key");
335335
}
336336

337337
private String extractPath(DbAction action) {

0 commit comments

Comments
 (0)