Activiti+Oracle 报错ORA-00942: 表或视图不存在启动项目时不能自动建表或更新表
给我启发的参考文章链接(但并没有找到根本原因)
Activiti+oracle 启动项目时不能自动建表或更新表的问题分析及解决办法
https://www.cnblogs.com/jiqiyoudu/p/5498302.html
问题
我参考上述文章链接的写法后,发现治标不治本,如果有这段配置存在,
除了第一次还能正常启动项目外,后面再启动,就会报出重复建表的错误。需要重新注释。于是就思考,这个报错到底是为什么?
先来说下答案:
答案:使用的这个Oracle数据库,数据库权限配置了【DBA最高管理员】Schema权限导致的。如果你不配置上述databaseSchema来指定某个具体数据库,就会出现找不到表现象。
好,再来说说我当时遇到的情景,注释的那句
忽略,当时是参考上面的博客加上去的,后来发现根本问题不在这里,就删除了。
这是activiti常用的配置
<?xml version="1.0" encoding="UTF-8"?><bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="databaseSchemaUpdate" value="true"/>
<property name="jobExecutorActivate" value="false"/>
<property name="asyncExecutorEnabled" value="true"/>
<property name="asyncExecutorActivate" value="false"/>
<property name="history" value="none"/>
<!--如果启动项目报表ACT_相关table不存在的异常,则解开下面注释,value值设置为jdbc.username一样的值,启动项目就会自动创建表,自动建完表后,重新注释掉下面这句,再次重启项目即可-->
<!--<property name="databaseSchema" value="username"/>-->
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
问题再现:
这段被注释配置并不需要,相关书籍,网上资料,甚至官方文档里都没有提及该配置。
然后:
项目上在Oracle库里部署了三个库:
1.中文繁体
2.中文简体
3.英文
结果:
中文简体,英文库里均能自动创建activiti相关表
唯独【中文繁体】无法创建表,启动项目报错:后来是加上了这个配置
才解决创建表的问题
一直没想明白根本原因,我自己归结为activiti本身在oracle环境下可能存在问题。
最后请教组里老大,老大怀疑这个库肯定有某个地方与其他两个库配置不同
让现场运维帮忙查看下:
结果一查一个准:
第一个繁体库配置了DBA最高管理员Schema权限,这个繁体库的用户是管理员
而另外两个则是普通用户
根本原因定位到了。神清气爽
当时我还不懂这个用户为DBA管理员与其他两个数据库有什么不同。老大做了一个形象的解释:
Oracle数据库,每个库对应一个用户,
好比一栋房子,每个房间归一个用户,用户有钥匙可以开门,每个用户也只能打开自己对的房间,访问自己的那个数据库。
而DBA管理员就相当于房东,它拥有所有的钥匙,想开哪个就开哪个。
如果activiti配置中没有指定databaseSchema,则管理员用户会默认指定一个房间打开,但是这个默认房间是不是我们想要的那个数据库,就不一定了。结果就导致:activiti检查表是否存在时,是去默认C库里查,发现有了,没检测出异常。然后实际操作时,用的却是A库,就直接报错:表查不到。(这个默认C库可能实际存在,也可能不存在,只是个虚拟的库)