Browse Source
Created NamingStrategy and a default implementation that replicates the current solution. Several unit tests illustrates how to override the default and plugin a custom solution including a ThreadLocal, contextual one that could be user-based if, for example, Spring Security's SecurityContextHolder was used.pull/13/head
17 changed files with 595 additions and 29 deletions
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2017 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.jdbc.mapping.model; |
||||||
|
|
||||||
|
/** |
||||||
|
* Basic implementation of {@link NamingStrategy} with no schema, table based on {@link Class} and |
||||||
|
* column name based on {@link JdbcPersistentProperty}. |
||||||
|
* |
||||||
|
* NOTE: Can also be used as an adapter. Create an anonymous subclass and override any settings to implement |
||||||
|
* a different strategy on the fly. |
||||||
|
* |
||||||
|
* @author Greg Turnquist |
||||||
|
*/ |
||||||
|
public class DefaultNamingStrategy implements NamingStrategy { |
||||||
|
|
||||||
|
/** |
||||||
|
* No schema at all! |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String getSchema() { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Look up the {@link Class}'s simple name. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String getTableName(Class<?> type) { |
||||||
|
return type.getSimpleName(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Look up the {@link JdbcPersistentProperty}'s name. |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String getColumnName(JdbcPersistentProperty property) { |
||||||
|
return property.getName(); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2017 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.jdbc.mapping.model; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Greg Turnquist |
||||||
|
*/ |
||||||
|
public interface NamingStrategy { |
||||||
|
|
||||||
|
String getSchema(); |
||||||
|
|
||||||
|
String getTableName(Class<?> type); |
||||||
|
|
||||||
|
String getColumnName(JdbcPersistentProperty property); |
||||||
|
|
||||||
|
default String getQualifiedTableName(Class<?> type) { |
||||||
|
return this.getSchema() + (this.getSchema().equals("") ? "" : ".") + this.getTableName(type); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,214 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2017 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.jdbc.core; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*; |
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
import java.util.function.Consumer; |
||||||
|
|
||||||
|
import org.assertj.core.api.SoftAssertions; |
||||||
|
import org.junit.Test; |
||||||
|
import org.springframework.data.annotation.Id; |
||||||
|
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.NamingStrategy; |
||||||
|
import org.springframework.data.mapping.PropertyPath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Unit tests to verify a contextual {@link NamingStrategy} implementation that customizes using a user-centric {@link ThreadLocal}. |
||||||
|
* |
||||||
|
* NOTE: Due to the need to verify SQL generation and {@link SqlGenerator}'s package-private status suggests |
||||||
|
* this unit test exist in this package, not {@literal org.springframework.data.jdbc.mappings.model}. |
||||||
|
* |
||||||
|
* @author Greg Turnquist |
||||||
|
*/ |
||||||
|
public class SqlGeneratorContextBasedNamingStrategyUnitTests { |
||||||
|
|
||||||
|
private final ThreadLocal<String> userHandler = new ThreadLocal<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Use a {@link DefaultNamingStrategy}, but override the schema with a {@link ThreadLocal}-based setting. |
||||||
|
*/ |
||||||
|
private final NamingStrategy contextualNamingStrategy = new DefaultNamingStrategy() { |
||||||
|
@Override |
||||||
|
public String getSchema() { |
||||||
|
return userHandler.get(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void findOne() { |
||||||
|
|
||||||
|
testAgainstMultipleUsers(user -> { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(contextualNamingStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.getFindOne(); |
||||||
|
|
||||||
|
SoftAssertions softAssertions = new SoftAssertions(); |
||||||
|
softAssertions.assertThat(sql) //
|
||||||
|
.startsWith("SELECT") //
|
||||||
|
.contains(user + ".DummyEntity.id AS id,") //
|
||||||
|
.contains(user + ".DummyEntity.name AS name,") //
|
||||||
|
.contains("ref.l1id AS ref_l1id") //
|
||||||
|
.contains("ref.content AS ref_content") //
|
||||||
|
.contains("FROM " + user + ".DummyEntity"); |
||||||
|
softAssertions.assertAll(); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteFirstLevel() { |
||||||
|
|
||||||
|
testAgainstMultipleUsers(user -> { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(contextualNamingStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo( |
||||||
|
"DELETE FROM " + user + ".ReferencedEntity WHERE " + user + ".DummyEntity = :rootId"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteAllSecondLevel() { |
||||||
|
|
||||||
|
testAgainstMultipleUsers(user -> { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(contextualNamingStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo( |
||||||
|
"DELETE FROM " + user + ".SecondLevelReferencedEntity " + |
||||||
|
"WHERE " + user + ".ReferencedEntity IN " + |
||||||
|
"(SELECT l1id FROM " + user + ".ReferencedEntity " + |
||||||
|
"WHERE " + user + ".DummyEntity = :rootId)"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void deleteAll() { |
||||||
|
|
||||||
|
testAgainstMultipleUsers(user -> { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(contextualNamingStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteAllSql(null); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo("DELETE FROM " + user + ".DummyEntity"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteAllFirstLevel() { |
||||||
|
|
||||||
|
testAgainstMultipleUsers(user -> { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(contextualNamingStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo( |
||||||
|
"DELETE FROM " + user + ".ReferencedEntity WHERE " + user + ".DummyEntity IS NOT NULL"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteSecondLevel() { |
||||||
|
|
||||||
|
testAgainstMultipleUsers(user -> { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(contextualNamingStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo( |
||||||
|
"DELETE FROM " + user + ".SecondLevelReferencedEntity " + |
||||||
|
"WHERE " + user + ".ReferencedEntity IN " + |
||||||
|
"(SELECT l1id FROM " + user + ".ReferencedEntity " + |
||||||
|
"WHERE " + user + ".DummyEntity IS NOT NULL)"); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take a set of user-based assertions and run them against multiple users, in different threads. |
||||||
|
*/ |
||||||
|
private void testAgainstMultipleUsers(Consumer<String> testAssertions) { |
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(2); |
||||||
|
|
||||||
|
threadedTest("User1", latch, testAssertions); |
||||||
|
threadedTest("User2", latch, testAssertions); |
||||||
|
|
||||||
|
try { |
||||||
|
latch.await(10L, TimeUnit.SECONDS); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Inside a {@link Runnable}, fetch the {@link ThreadLocal}-based username and execute the provided |
||||||
|
* set of assertions. Then signal through the provided {@link CountDownLatch}. |
||||||
|
*/ |
||||||
|
private void threadedTest(String user, CountDownLatch latch, Consumer<String> testAssertions) { |
||||||
|
|
||||||
|
new Thread(() -> { |
||||||
|
userHandler.set(user); |
||||||
|
|
||||||
|
testAssertions.accept(user); |
||||||
|
|
||||||
|
latch.countDown(); |
||||||
|
}).start(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Plug in a custom {@link NamingStrategy} for this test case. |
||||||
|
*/ |
||||||
|
private SqlGenerator configureSqlGenerator(NamingStrategy namingStrategy) { |
||||||
|
|
||||||
|
JdbcMappingContext context = new JdbcMappingContext(namingStrategy); |
||||||
|
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class); |
||||||
|
|
||||||
|
return new SqlGenerator(context, persistentEntity, new SqlGeneratorSource(context)); |
||||||
|
} |
||||||
|
|
||||||
|
static class DummyEntity { |
||||||
|
|
||||||
|
@Id Long id; |
||||||
|
String name; |
||||||
|
ReferencedEntity ref; |
||||||
|
} |
||||||
|
|
||||||
|
static class ReferencedEntity { |
||||||
|
|
||||||
|
@Id Long l1id; |
||||||
|
String content; |
||||||
|
SecondLevelReferencedEntity further; |
||||||
|
} |
||||||
|
|
||||||
|
static class SecondLevelReferencedEntity { |
||||||
|
|
||||||
|
@Id Long l2id; |
||||||
|
String something; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,201 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2017 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.jdbc.core; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.*; |
||||||
|
|
||||||
|
import org.assertj.core.api.SoftAssertions; |
||||||
|
import org.junit.Test; |
||||||
|
import org.springframework.data.annotation.Id; |
||||||
|
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.mapping.PropertyPath; |
||||||
|
|
||||||
|
/** |
||||||
|
* Unit tests to a fixed {@link NamingStrategy} implementation containing a hard wired schema, table, and property prefix. |
||||||
|
* |
||||||
|
* NOTE: Due to the need to verify SQL generation and {@link SqlGenerator}'s package-private status suggests |
||||||
|
* this unit test exist in this package, not {@literal org.springframework.data.jdbc.mappings.model}. |
||||||
|
* |
||||||
|
* @author Greg Turnquist |
||||||
|
*/ |
||||||
|
public class SqlGeneratorFixedNamingStrategyUnitTests { |
||||||
|
|
||||||
|
final NamingStrategy fixedCustomTablePrefixStrategy = new DefaultNamingStrategy() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getSchema() { |
||||||
|
return "FixedCustomSchema"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getTableName(Class<?> type) { |
||||||
|
return "FixedCustomTablePrefix_" + type.getSimpleName(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(JdbcPersistentProperty property) { |
||||||
|
return "FixedCustomPropertyPrefix_" + property.getName(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
final NamingStrategy upperCaseLowerCaseStrategy = new DefaultNamingStrategy() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getTableName(Class<?> type) { |
||||||
|
return type.getSimpleName().toUpperCase(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getColumnName(JdbcPersistentProperty property) { |
||||||
|
return property.getName().toLowerCase(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void findOneWithOverriddenFixedTableName() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(fixedCustomTablePrefixStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.getFindOne(); |
||||||
|
|
||||||
|
SoftAssertions softAssertions = new SoftAssertions(); |
||||||
|
softAssertions.assertThat(sql) //
|
||||||
|
.startsWith("SELECT") //
|
||||||
|
.contains("FixedCustomSchema.FixedCustomTablePrefix_DummyEntity.FixedCustomPropertyPrefix_id AS FixedCustomPropertyPrefix_id,") //
|
||||||
|
.contains("FixedCustomSchema.FixedCustomTablePrefix_DummyEntity.FixedCustomPropertyPrefix_name AS FixedCustomPropertyPrefix_name,") //
|
||||||
|
.contains("ref.FixedCustomPropertyPrefix_l1id AS ref_FixedCustomPropertyPrefix_l1id") //
|
||||||
|
.contains("ref.FixedCustomPropertyPrefix_content AS ref_FixedCustomPropertyPrefix_content") //
|
||||||
|
.contains("FROM FixedCustomSchema.FixedCustomTablePrefix_DummyEntity"); |
||||||
|
softAssertions.assertAll(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void findOneWithUppercasedTablesAndLowercasedColumns() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(upperCaseLowerCaseStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.getFindOne(); |
||||||
|
|
||||||
|
SoftAssertions softAssertions = new SoftAssertions(); |
||||||
|
softAssertions.assertThat(sql) //
|
||||||
|
.startsWith("SELECT") //
|
||||||
|
.contains("DUMMYENTITY.id AS id,") //
|
||||||
|
.contains("DUMMYENTITY.name AS name,") //
|
||||||
|
.contains("ref.l1id AS ref_l1id") //
|
||||||
|
.contains("ref.content AS ref_content") //
|
||||||
|
.contains("FROM DUMMYENTITY"); |
||||||
|
softAssertions.assertAll(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteFirstLevel() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(fixedCustomTablePrefixStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo("DELETE FROM FixedCustomSchema.FixedCustomTablePrefix_ReferencedEntity " + |
||||||
|
"WHERE FixedCustomSchema.FixedCustomTablePrefix_DummyEntity = :rootId"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteAllSecondLevel() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(fixedCustomTablePrefixStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo( |
||||||
|
"DELETE FROM FixedCustomSchema.FixedCustomTablePrefix_SecondLevelReferencedEntity " + |
||||||
|
"WHERE FixedCustomSchema.FixedCustomTablePrefix_ReferencedEntity IN " + |
||||||
|
"(SELECT FixedCustomPropertyPrefix_l1id " + |
||||||
|
"FROM FixedCustomSchema.FixedCustomTablePrefix_ReferencedEntity " + |
||||||
|
"WHERE FixedCustomSchema.FixedCustomTablePrefix_DummyEntity = :rootId)"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void deleteAll() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(fixedCustomTablePrefixStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteAllSql(null); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo("DELETE FROM FixedCustomSchema.FixedCustomTablePrefix_DummyEntity"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteAllFirstLevel() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(fixedCustomTablePrefixStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo("DELETE FROM FixedCustomSchema.FixedCustomTablePrefix_ReferencedEntity " + |
||||||
|
"WHERE FixedCustomSchema.FixedCustomTablePrefix_DummyEntity IS NOT NULL"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test // DATAJDBC-107
|
||||||
|
public void cascadingDeleteSecondLevel() { |
||||||
|
|
||||||
|
SqlGenerator sqlGenerator = configureSqlGenerator(fixedCustomTablePrefixStrategy); |
||||||
|
|
||||||
|
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class)); |
||||||
|
|
||||||
|
assertThat(sql).isEqualTo( |
||||||
|
"DELETE FROM FixedCustomSchema.FixedCustomTablePrefix_SecondLevelReferencedEntity " + |
||||||
|
"WHERE FixedCustomSchema.FixedCustomTablePrefix_ReferencedEntity IN " + |
||||||
|
"(SELECT FixedCustomPropertyPrefix_l1id " + |
||||||
|
"FROM FixedCustomSchema.FixedCustomTablePrefix_ReferencedEntity " + |
||||||
|
"WHERE FixedCustomSchema.FixedCustomTablePrefix_DummyEntity IS NOT NULL)"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Plug in a custom {@link NamingStrategy} for this test case. |
||||||
|
* |
||||||
|
* @param namingStrategy |
||||||
|
*/ |
||||||
|
private SqlGenerator configureSqlGenerator(NamingStrategy namingStrategy) { |
||||||
|
|
||||||
|
JdbcMappingContext context = new JdbcMappingContext(namingStrategy); |
||||||
|
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class); |
||||||
|
return new SqlGenerator(context, persistentEntity, new SqlGeneratorSource(context)); |
||||||
|
} |
||||||
|
|
||||||
|
static class DummyEntity { |
||||||
|
|
||||||
|
@Id Long id; |
||||||
|
String name; |
||||||
|
ReferencedEntity ref; |
||||||
|
} |
||||||
|
|
||||||
|
static class ReferencedEntity { |
||||||
|
|
||||||
|
@Id Long l1id; |
||||||
|
String content; |
||||||
|
SecondLevelReferencedEntity further; |
||||||
|
} |
||||||
|
|
||||||
|
static class SecondLevelReferencedEntity { |
||||||
|
|
||||||
|
@Id Long l2id; |
||||||
|
String something; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue