play framework慎用Fixture.deleteAll()

最近嘗試使用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()!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章