您的位置:首页 > 数据库

Activiti用Api创建数据库表

2013-08-02 10:15 323 查看
先上代码:

public void init() throws Exception{
DataSource ds = EsenServer.getConnFactoryManager().getDataSource(null, true).getDataSource();
ConnectionFactory fct = EsenServer.getConnFactoryManager().getDefaultConnectionFactory();
DbDefiner dbf = fct.getDbDefiner();

ProcessEngineConfiguration pec = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration()
.setDataSource(ds).setDatabaseType("oracle");

boolean historyTablesNullExist = false;
boolean historyTablesAllExist = false;
boolean idTablesAllExist = false;
boolean idTablesNullExist = false;
boolean engineTablesNullExist = false;
boolean engineTablesAllExist = false;
List<String> missingTableNames = null;
Connection conn = ds.getConnection();
try{
historyTablesNullExist = tablesNullExist(dbf, conn, historyTables);
historyTablesAllExist = tablesAllExist(dbf, conn, historyTables);
idTablesNullExist = tablesNullExist(dbf, conn, identityTables);
idTablesAllExist = tablesAllExist(dbf, conn, identityTables);
engineTablesNullExist = tablesNullExist(dbf, conn, engineTables);
engineTablesAllExist = tablesAllExist(dbf, conn, engineTables);
missingTableNames = getAllMissingTableNames(dbf, conn);
}finally{
if(conn!=null){
conn.close();
}
}
/**
* 判断数据库中是否有引擎核心表或视图、历史表或视图和身份识别表或视图,
* 若都不存在,则给当前ProcessEngineConfiguration添加创建数据库表的属性DatabaseSchemaUpdate;
* 若都存在,则不设置创建表的属性DatabaseSchemaUpdate;
* 其他情况下,则抛出异常:数据库表[...]缺失
*/
if(historyTablesNullExist && idTablesNullExist && engineTablesNullExist){
pec.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_CREATE);
}else if(historyTablesAllExist && idTablesAllExist && engineTablesAllExist){
//do nothing
}else{
throw new Exception("数据库表" + missingTableNames.toString() + "缺失");
}

processEngine = pec.buildProcessEngine();
ProcessEngines.registerProcessEngine(processEngine);

workflow = this;
}

在这里,不是以配置文件的形式创建引擎的,而是直接以Api编码的形式创建工作流引擎,为了让引擎在构建过程中,创建数据库表,需要给引擎配置对象pec设置属性:

pec.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_CREATE);
这样设置好了后,如果是第一次启动运行是没有问题的,因为最开始我们的数据库里面是没有工作流引擎的数据库表的。但是,在重复运行时,就会报错:表或视图已经存在!

原因是:当我们给工作流引擎的配置对象设置了创建数据库表的属性后,工作流引擎每次启动时都会去执行创建表的动作,而引擎本身只是简单的检查一下当前数据库用户有权限查看的所有数据库表中是否有ACT_RU_EXECUTION这张表,而没有对历史表和身份识别表做检查。所以仍然会再次执行创建历史表和身份识别表的ddl语句,进而引起SQLException:表或视图名已存在!因此,可以看到上面的代码中,有很大一部分是在做数据库表是否存在的检查。

另外还需要注意一点的是:在服务器启动时可能还会报错:当查询schema.version时,ACT_GE_PROPERTY表或视图不存在。而这时当你去查看自己的数据库表时,确实数据库中是没有ACT_GE_PROPERTY这张表的。这就奇怪了,既然没有,为什么引擎在创建数据库表时没有创建这张表呢?这是因为引擎在创建表前做的检查存在bug,引擎在检查数据库表中是否存在表ACT_RU_EXECUTION时,检查的不仅是当前用户的表空间,而且还检查了当前用户有权限查看的所有其他数据库表空间,也就是说如果当前用户具有系统管理员权限,那么只要整个数据库系统中,某个用户的表空间中存在这张名为ACT_RU_EXECUTION的表或视图时,我们的引擎在创建表时就认为该表已经存在,进而不会在我们自己的表空间创建该表。而在查询时,引擎只是在我们的表空间中查找,当然找不到了。因为那张被认为存在的表在某个用户的表空间而不在我们自己的表空间。为了彻底解决这个问题,我们只能修改引擎源代码了,更改引擎检查数据库表是否存在的方法:DbSqlSession类中的isTablePresent方法。至于怎样改,大家看看源代码就应该清楚了,方法会有很多,相信大家各有各的选择,这里就不做讨论了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: