我们在我们的项目中使用 hsqldb 并且运行良好。我们当前配置为使用进程内文件数据库,并且我们的 DriverManagerDataSource、LocalContainerEntityManagerFactoryBean 和 TransactionManager 在我们的上下文 XML 文件中都被实例化为 bean:
<bean id="databaseValidator" class="com.apps.database.DatabaseValidator"></bean>
<bean id="dataSource" depends-on="databaseValidator" class="com.apps.database.DriverManagerDataSourceWithDirectory">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:db/theDB" />
<property name="username" value="--------" />
<property name="password" value="--------" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.apps.model.logic</value>
<value>com.apps.jpa</value>
</list>
</property>
<property name="mappingResources">
<list>
<value>Setting.hbm.xml</value>
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="HSQL" />
</bean>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
每当我们必须通过引入新实体或修改现有实体的字段来修改数据库模式时,事情就会变得棘手。也就是说,它要求我们所有的开发人员在他们的开发环境中删除我们文件数据库的现有副本并重新插入更新的副本。我希望这是一个自动过程,以便在应用程序启动时,我们可以在尝试连接之前检查现有数据库文件是否具有正确的架构。事实上,我想在每次应用程序启动时验证数据库的架构,以确保最终用户(在非开发环境中)可以将他们的数据库迁移到当前架构。
为了实现这一点,我们创建了一个 bean(databaseValidator - 见上文和下文),它在尝试通过创建代码中的 EntityManagerFactory 并调用“afterPropertiesSet”来验证模式之前启动。这实际上起到了作用 - 如果架构不匹配,它会失败,如果架构有效,它就会成功。虽然这有效,但它保留了我们的数据库文件,因此我们无法删除它们并用更新的数据库文件替换它们。由于我们无法删除文件,因此我们无法用更新的文件数据库替换它们。
总的来说,我觉得这不是在连接到文件数据库之前验证文件数据库架构的最佳方法。我有一种感觉,我们可能想利用现有的 EntityManagerFactory(如上面的 XML 文件中所定义)来确定模式是否有效,但我不确定如何利用它的异常抛出。有人对我们如何以编程方式测试文件数据库的模式有更好的建议吗?
private boolean isTheSchemaValid() {
boolean isValid = false;
LocalContainerEntityManagerFactoryBean emf = null;
try {
emf = new LocalContainerEntityManagerFactoryBean();
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:file:db/theDB");
dataSource.setUsername("--------");
dataSource.setPassword("--------");
emf.setDataSource(dataSource);
Properties jpaProperties = new Properties();
jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
jpaProperties.setProperty("hibernate.hbm2ddl.auto", "validate");
emf.setJpaProperties(jpaProperties);
emf.setPackagesToScan("com.test.model.logic", "com.test.jpa");
emf.setMappingResources("Setting.hbm.xml");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabasePlatform("HSQL");
emf.setJpaVendorAdapter(adapter);
emf.afterPropertiesSet();
isValid = true;
} catch (Exception ex) {
isValid = false;
} finally {
emf = null;
}
return isValid;
}
我很乐意根据需要提供更多信息。谢谢!