Autowired Spring 带 H2 数据库的数据存储库在测试中未将实体 table 或字段转换为预期的 Hibernate 命名策略
Autowired Spring Data repository w/ H2 database in test not translating Entity table or fields to intended Hibernate naming strategy
问题
我有一个 Spring 配置 class 用于生成内存中的 H2 数据库以进行集成测试。我还有一个集成测试,应该使用 H2 数据库作为它的方法。其中一项测试(原始 JDBC 查询)成功,因此我知道数据库至少部分是从脚本生成的。但是,JPA 实体(假设其名为 SampleThing 并具有相应的 SampleThingRepository)在生成 SQL.
时似乎没有使用正确的命名策略
在 IntegrationConfigTest 文件中,我定义了两个测试:
- IntegrationConfigTest.verifyEmbeddedDatabase(通过)
- IntegrationConfigTest.ormMappingShouldWork(失败并出现异常 org.h2.jdbc.JdbcSQLException: Table "sampleThings" 未找到;)
预期
我希望存储库方法 findOne(1L) 为 SQL 生成什么:
- select samplethin0_.id 作为 id1_6_0_, samplethin0_.is_active 作为 is_active2_6_0_, samplethin0_.name 作为 name3_6_0_, samplethin0_.list_order 作为 list_orde4_6_0_ 来自 testDb.sample_things samplethin0_ 其中 samplethin_.id=?
实际生成的内容:
- select samplethin0_.id 作为 id1_6_0_, samplethin0_.isActive 作为 isActive2_6_0_, samplethin0_.name 作为 name3_6_0_, samplethin0_.listOrder 作为 listOrde4_6_0_ 来自 testDb.sampleThings samplethin0_ 其中 samplethin_.id=?
在 IntegrationConfig 中,我将 hibernate.naming_strategy 定义为 ImprovedNamingStrategy(这是我想要的)。您可以假设我的实体 SampleThing 规定了一个 table 名称,以及应该转换为蛇形大小写的驼峰式大小写的列名。任何帮助将不胜感激。
文件
这是 IntegrationConfig,我设置 H2 数据库的配置:
@Ignore("Not a test")
@Configuration
@EnableJpaRepositories("com.company.project.repository")
public class IntegrationConfig {
@Value("classpath:checks_off.sql")
private Resource checksOffScript;
@Value("classpath:set_mode.sql")
private Resource setModeScript;
@Value("classpath:test_schema.sql")
private Resource schemaScript;
@Value("classpath:test_import.sql")
private Resource importScript;
@Value("classpath:checks_on.sql")
private Resource checksOnScript;
@Bean
public DataSource dataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:h2:mem:testDb;DB_CLOSE_DELAY=-1;MODE=Mysql;DATABASE_TO_UPPER=false");
dataSourceBuilder.driverClassName("org.h2.Driver");
return dataSourceBuilder.build();
}
@Bean
public DataSourceInitializer dataSourceInitializer() {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource());
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(checksOffScript);
populator.addScript(setModeScript);
populator.addScript(schemaScript);
populator.addScript(importScript);
populator.addScript(checksOnScript);
return populator;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("com.company.project");
entityManagerFactoryBean.setJpaProperties(getPropeties());
entityManagerFactoryBean.setJpaVendorAdapter(getJpaVendorAdapter());
return entityManagerFactoryBean;
}
private Properties getPropeties(){
Properties properties = new Properties();
properties.put("hibernate.current_session_context_class", SpringSessionContext.class.getName());
properties.put("hibernate.default_schema", "testDb");
properties.put("hibernate.naming_strategy", org.hibernate.cfg.ImprovedNamingStrategy.class.getName());
return properties;
}
private JpaVendorAdapter getJpaVendorAdapter(){
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.H2);
adapter.setGenerateDdl(true);
adapter.setShowSql(true);
return adapter;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
这是 IntegrationConfigTest,class 包含两个测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationConfig.class)
public class IntegrationConfigTest {
JdbcTemplate jdbcTemplate;
@Autowired
SampleThingRepository sampleThingRepository;
@Autowired
DataSource dataSource;
@Before
public void setUp() {
jdbcTemplate = new JdbcTemplate(dataSource);
}
String getThingByOrder(int order) {
return jdbcTemplate.queryForObject(
"SELECT name FROM sample_things WHERE list_order = ?",
String.class, order);
}
@Test
public void verifyEmbeddedDatabase() {
String firstThing = getThingByOrder(1);
assertThat(firstThing, is("This thing"));
String secondThing = getThingByOrder(2);
assertThat(secondThing, is("That thing"));
}
@Test
public void ormMappingShouldWork() {
SampleThing sampleThing = sampleThingRepository.findOne(1L);
assertThat(sampleThing.getName(), is("This thing"));
assertThat(sampleThing.getOrder(), is(1));
}
}
您的 NamingStrategy
似乎没有被应用。将 hibernate.naming_strategy
更改为 hibernate.ejb.naming_strategy
以便您的休眠属性如下所示;
properties.put("hibernate.ejb.naming_strategy", org.hibernate.cfg.ImprovedNamingStrategy.class.getName());
问题
我有一个 Spring 配置 class 用于生成内存中的 H2 数据库以进行集成测试。我还有一个集成测试,应该使用 H2 数据库作为它的方法。其中一项测试(原始 JDBC 查询)成功,因此我知道数据库至少部分是从脚本生成的。但是,JPA 实体(假设其名为 SampleThing 并具有相应的 SampleThingRepository)在生成 SQL.
时似乎没有使用正确的命名策略在 IntegrationConfigTest 文件中,我定义了两个测试:
- IntegrationConfigTest.verifyEmbeddedDatabase(通过)
- IntegrationConfigTest.ormMappingShouldWork(失败并出现异常 org.h2.jdbc.JdbcSQLException: Table "sampleThings" 未找到;)
预期
我希望存储库方法 findOne(1L) 为 SQL 生成什么:
- select samplethin0_.id 作为 id1_6_0_, samplethin0_.is_active 作为 is_active2_6_0_, samplethin0_.name 作为 name3_6_0_, samplethin0_.list_order 作为 list_orde4_6_0_ 来自 testDb.sample_things samplethin0_ 其中 samplethin_.id=?
实际生成的内容:
- select samplethin0_.id 作为 id1_6_0_, samplethin0_.isActive 作为 isActive2_6_0_, samplethin0_.name 作为 name3_6_0_, samplethin0_.listOrder 作为 listOrde4_6_0_ 来自 testDb.sampleThings samplethin0_ 其中 samplethin_.id=?
在 IntegrationConfig 中,我将 hibernate.naming_strategy 定义为 ImprovedNamingStrategy(这是我想要的)。您可以假设我的实体 SampleThing 规定了一个 table 名称,以及应该转换为蛇形大小写的驼峰式大小写的列名。任何帮助将不胜感激。
文件
这是 IntegrationConfig,我设置 H2 数据库的配置:
@Ignore("Not a test")
@Configuration
@EnableJpaRepositories("com.company.project.repository")
public class IntegrationConfig {
@Value("classpath:checks_off.sql")
private Resource checksOffScript;
@Value("classpath:set_mode.sql")
private Resource setModeScript;
@Value("classpath:test_schema.sql")
private Resource schemaScript;
@Value("classpath:test_import.sql")
private Resource importScript;
@Value("classpath:checks_on.sql")
private Resource checksOnScript;
@Bean
public DataSource dataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.url("jdbc:h2:mem:testDb;DB_CLOSE_DELAY=-1;MODE=Mysql;DATABASE_TO_UPPER=false");
dataSourceBuilder.driverClassName("org.h2.Driver");
return dataSourceBuilder.build();
}
@Bean
public DataSourceInitializer dataSourceInitializer() {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource());
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(checksOffScript);
populator.addScript(setModeScript);
populator.addScript(schemaScript);
populator.addScript(importScript);
populator.addScript(checksOnScript);
return populator;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("com.company.project");
entityManagerFactoryBean.setJpaProperties(getPropeties());
entityManagerFactoryBean.setJpaVendorAdapter(getJpaVendorAdapter());
return entityManagerFactoryBean;
}
private Properties getPropeties(){
Properties properties = new Properties();
properties.put("hibernate.current_session_context_class", SpringSessionContext.class.getName());
properties.put("hibernate.default_schema", "testDb");
properties.put("hibernate.naming_strategy", org.hibernate.cfg.ImprovedNamingStrategy.class.getName());
return properties;
}
private JpaVendorAdapter getJpaVendorAdapter(){
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.H2);
adapter.setGenerateDdl(true);
adapter.setShowSql(true);
return adapter;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
这是 IntegrationConfigTest,class 包含两个测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationConfig.class)
public class IntegrationConfigTest {
JdbcTemplate jdbcTemplate;
@Autowired
SampleThingRepository sampleThingRepository;
@Autowired
DataSource dataSource;
@Before
public void setUp() {
jdbcTemplate = new JdbcTemplate(dataSource);
}
String getThingByOrder(int order) {
return jdbcTemplate.queryForObject(
"SELECT name FROM sample_things WHERE list_order = ?",
String.class, order);
}
@Test
public void verifyEmbeddedDatabase() {
String firstThing = getThingByOrder(1);
assertThat(firstThing, is("This thing"));
String secondThing = getThingByOrder(2);
assertThat(secondThing, is("That thing"));
}
@Test
public void ormMappingShouldWork() {
SampleThing sampleThing = sampleThingRepository.findOne(1L);
assertThat(sampleThing.getName(), is("This thing"));
assertThat(sampleThing.getOrder(), is(1));
}
}
您的 NamingStrategy
似乎没有被应用。将 hibernate.naming_strategy
更改为 hibernate.ejb.naming_strategy
以便您的休眠属性如下所示;
properties.put("hibernate.ejb.naming_strategy", org.hibernate.cfg.ImprovedNamingStrategy.class.getName());