最近嘗試使用play framework來開發網站,它的開發模式實在好用:修改類後自動加載而無需重啓、可配置自動重建表和插入測試數據等,但是看起來美好的東西也有陷阱。
爲了每次修改類和啓動程序的時候,只使用預定測試的數據,所以我寫了一個類,當程序啓動的時候會清除表數據並導入寫在yml文件裏的數據。
@OnApplicationStart
public class Bootstrap extends Job {
@Override
public void doJob() {
Fixtures.deleteAll();
Fixtures.load("data.yml");
}
}
由於我們項目使用的數據庫是sybase,所以我乾脆配置數據庫爲sybase測試程序,並且數據庫裏已經有一些不是此程序用的表。結果程序啓動後整個數據庫的表數據被清空!
原因就是Fixtures.deleteAll()會遍歷數據庫的所有表,並把每個表都truncate或者delete了。
用Fixtures.deleteAllModels()這個方法可以只刪除定義的Model的數據,而不會刪除其他表。這個方法也是有缺點的,就是你繼承JPABase的類對應的表都會去清空,例如因爲Model裏默認有個Long類型的id字段
@MappedSuperclass
public class Model extends GenericModel {
@Id
@GeneratedValue
public Long id;
public Long getId() {
return id;
}
}
但是我想改用UUID作ID,所以繼承了GenericModel(GenericModel是繼承JPABase的)寫了個類讓實際用的模型類繼承
@MappedSuperclass
public class ModelWithUuid extends GenericModel {
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid.hex")
@Column(columnDefinition="char(32)")
public String id;
public String getId() {
return id;
}
}
程序運行的時候就會出現這個錯誤
play.exceptions.UnexpectedException: Model ModelWithUuid is not managed by any plugin
如果每個繼承Model的類都會用到,可以直接用Fixtures.deleteAllModels()刪除表數據,不然用Fixtures.delete(User.class)這樣的方法寫上要自動刪除表數據的類了。
@OnApplicationStart
public class Bootstrap extends Job {
@Override
public void doJob() {
Fixtures.delete(User.class);
Fixtures.delete(Admin.class);
Fixtures.delete(Menu.class);
Fixtures.load("data.yml");
}
}
慎用Fixtures.deleteAll()!