И давайте не будем забывать, что средства доступа дают вам гибкость при работе с несколькими потоками.
Мое текущее решение выглядит так:
@Override
protected String[] getConfigLocations() {
createHSQLDBSchemas ();
return new String[]{
"test-spring-config.xml"
};
}
private static boolean hsqldbSchemasCreated = false;
public static void createHSQLDBSchemas ()
{
if (hsqldbSchemasCreated)
return;
try
{
log.info ("createHSQLDBSchemas");
Class.forName("org.hsqldb.jdbcDriver").newInstance();
Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:test", "sa", "");
Statement stmt = c.createStatement ();
String sql;
sql = "CREATE SCHEMA xxx AUTHORIZATION DBA";
log.info (sql);
stmt.execute (sql);
stmt.close ();
c.close ();
}
catch (Exception e)
{
throw new ShouldNotHappenException (e);
}
hsqldbSchemasCreated = true;
}
, но это выглядит как действительно уродливый взлом. Нет лучшего решения?
Мне кажется, что у вас есть воспроизводимая ошибка в коде создания DDL Hibernate. Вы должны сообщить об ошибке - это долгосрочное решение, но так все и делается в открытых источниках. Конечно, вы можете захотеть создать патч, но я никогда не считал, что базу кода Hibernate легко взломать.
Вы можете написать класс, реализующий InitializingBean :
public class SchemaCreator implements InitializingBean {
private String schema;
private DataSource dataSource;
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void afterPropertiesSet() throws Exception {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute("CREATE SCHEMA " + schema + " AUTHORIZATION DBA");
}
}
Затем вам нужно определить bean-компонент в вашем файле определения bean-компонента этого класса (я делаю снимок в темноте относительно того, как выглядят ваши существующие определения bean-компонентов).
<bean id="dataSource" class="...">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="sessionFactory" depends-on="schemaCreator" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
...
</bean>
<bean id="schemaCreator" class="SchemaCreator">
<property name="dataSource" ref="dataSource"/>
<property name="schema" value="TEST"/>
</bean>
Используя атрибут depends-on
bean-компонента Hibernate, Spring гарантирует, что bean-компонент schemaCreator
будет инициализирован во-первых, заставляя схему существовать как раз вовремя. Это также должно прояснить ваши намерения.