傳統 Hibernate 測試依賴外部資料庫,面臨環境依賴重、測試數據汙染、Schema 同步痛苦三大難題。HSQLDB 內存模式配合 Hibernate hbm2ddl.auto=create-drop,可在單元測試中秒級建立乾淨 Schema、獨立運行、零外部依賴,大幅提升 TDD 效率。
public class TestSchema {
static {
Configuration config = new Configuration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")
.setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver")
.setProperty("hibernate.connection.url", "jdbc:hsqldb:mem:testdb")
.setProperty("hibernate.connection.username", "sa")
.setProperty("hibernate.connection.password", "")
.setProperty("hibernate.connection.pool_size", "1")
.setProperty("hibernate.connection.autocommit", "true")
.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.HashtableCacheProvider")
.setProperty("hibernate.hbm2ddl.auto", "create-drop") // 關鍵:每次 SessionFactory 建立重建 Schema
.setProperty("hibernate.show_sql", "true")
.addClass(Player.class)
.addClass(BattingStint.class)
.addClass(FieldingStint.class)
.addClass(PitchingStint.class);
HibernateUtil.setSessionFactory(config.buildSessionFactory());
}
// 輔助方法:添加/重置測試數據
public static void addPlayer(Player p) { /* Hibernate save */ }
public static void reset() { /* JDBC 批量 DELETE,注意外鍵順序 */ }
}
jdbc:hsqldb:mem:testdb:純內存數據庫,JVM 結束即銷毀,零殘留。hbm2ddl.auto=create-drop:SessionFactory 建立時依映射自動建表,關閉時 Drop 表,保證每次測試 Schema 乾淨。HashtableCacheProvider:內存緩存,避免二級緩存干擾測試隔離性。public class PlayerTest extends TestCase {
@Override
protected void setUp() throws Exception {
TestSchema.reset(); // 每個測試方法前清空數據
}
public void testEligiblePositions() {
Player player = new Player("p1");
TestSchema.addPlayer(player);
FieldingStint stint = new FieldingStint("p1", 2004, "SEA", Position.CATCHER);
stint.setGames(20);
TestSchema.addFieldingStint(stint);
Set positions = player.getEligiblePositions(2004);
assertEquals(1, positions.size());
assertTrue(positions.contains(Position.CATCHER));
}
}
reset() 中直接用 session.connection() 批量 DELETE,注意關閉 Statement 而非 Connection(連接池 size=1,關閉連接會導致後續測試失效)。hibernate.cfg.xml 配置真實資料庫與連接池,代碼零修改。HSQLDB + Hibernate 內存測試模式,是持久層 TDD 的「標準裝備」,輕量、快速、可靠,值得每個 Java 團隊納入標準化測試基礎設施。