错误信息如下:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-10-18 16:55:05.465 ERROR 21540 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'remoteEntityManagerFactory' defined in class path resource [tech/powerjob/server/persistence/config/RemoteJpaConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: remotePersistenceUnit] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Error accessing index information: POWERJOB-PRODUCT.APP_INFO
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at tech.powerjob.server.PowerJobServerApplication.main(PowerJobServerApplication.java:33)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: remotePersistenceUnit] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Error accessing index information: POWERJOB-PRODUCT.APP_INFO
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
... 16 common frames omitted
Caused by: org.hibernate.exception.GenericJDBCException: Error accessing index information: POWERJOB-PRODUCT.APP_INFO
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.tool.schema.extract.internal.AbstractInformationExtractorImpl.convertSQLException(AbstractInformationExtractorImpl.java:118)
at org.hibernate.tool.schema.extract.internal.AbstractInformationExtractorImpl.getIndexes(AbstractInformationExtractorImpl.java:1165)
at org.hibernate.tool.schema.extract.internal.TableInformationImpl.indexes(TableInformationImpl.java:122)
at org.hibernate.tool.schema.extract.internal.TableInformationImpl.getIndex(TableInformationImpl.java:138)
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applyUniqueKeys(AbstractSchemaMigrator.java:388)
at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:90)
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:220)
at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:123)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:196)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:85)
at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:335)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
... 20 common frames omitted
Caused by: java.sql.SQLException: 调用中的无效参数
at oracle.jdbc.OracleDatabaseMetaData.getIndexInfo(OracleDatabaseMetaData.java:3777)
at com.zaxxer.hikari.pool.ProxyDatabaseMetaData.getIndexInfo(ProxyDatabaseMetaData.java:208)
at com.zaxxer.hikari.pool.HikariProxyDatabaseMetaData.getIndexInfo(HikariProxyDatabaseMetaData.java)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processIndexInfoResultSet(InformationExtractorJdbcDatabaseMetaDataImpl.java:112)
at org.hibernate.tool.schema.extract.internal.AbstractInformationExtractorImpl.getIndexes(AbstractInformationExtractorImpl.java:1125)
... 34 common frames omitted
经过仔细的排查,终于发现了导致这个错误的原因了。
引用官网文档中的介绍:
STEP1: 初始化数据库
调度服务器(powerjob-server)的持久化层基于Spring Data Jpa实现,对于能够直连数据库的应用,开发者仅需完成数据库的创建,即运行SQL:CREATE DATABASE IF NOT EXISTS powerjob-product
DEFAULT CHARSET utf8mb4
● PowerJob支持环境隔离,提供日常(daily)、预发(pre)和线上(product)三套环境,请根据使用的环境分别部署对应的数据库 powerjob-daily、powerjob-pre 和 powerjob-product。
我在oracle数据库里面新建了一个名为POWERJOB-PRODUCT的角色,在第一次启动的时候自动建表,重启服务的时候,发现启动不了,报错在上面了。这里介绍一下排查过程,刚开始以为是权限问题,我给这个用户库加上了dba的权限。然后跟着debug走,发现了错误所在:
public synchronized ResultSet getIndexInfo(String var1, String var2, String var3, boolean var4, boolean var5) throws SQLException {
Statement var6 = this.connection.createStatement();
if ((var2 == null || var2.length() == 0 || OracleSql.isValidObjectName(var2)) && (var3 == null || var3.length() == 0 || OracleSql.isValidObjectName(var3))) {
String var8;
if (!var5) {
boolean var7 = false;
try {
var7 = this.connection.getTransactionState().contains(TransactionState.TRANSACTION_STARTED);
} catch (SQLException var16) {
}
if (!var7) {
var8 = "analyze table " + (var2 == null ? "" : var2 + ".") + var3 + " compute statistics";
var6.executeUpdate(var8);
}
}
String var17 = "select null as table_cat,\n owner as table_schem,\n table_name,\n 0 as NON_UNIQUE,\n null as index_qualifier,\n null as index_name, 0 as type,\n 0 as ordinal_position, null as column_name,\n null as asc_or_desc,\n num_rows as cardinality,\n blocks as pages,\n null as filter_condition\nfrom all_tables\nwhere table_name = " + quoteDatabaseObjectName(var3) + "\n";
var8 = "";
if (var2 != null && var2.length() > 0) {
var8 = " and owner = " + quoteDatabaseObjectName(var2) + "\n";
}
String var9 = "select null as table_cat,\n i.owner as table_schem,\n i.table_name,\n decode (i.uniqueness, 'UNIQUE', 0, 1),\n null as index_qualifier,\n i.index_name,\n 1 as type,\n c.column_position as ordinal_position,\n c.column_name,\n null as asc_or_desc,\n i.distinct_keys as cardinality,\n i.leaf_blocks as pages,\n null as filter_condition\nfrom all_indexes i, all_ind_columns c\nwhere i.table_name = " + quoteDatabaseObjectName(var3) + "\n";
String var10 = "";
if (var2 != null && var2.length() > 0) {
var10 = " and i.owner = " + quoteDatabaseObjectName(var2) + "\n";
}
String var11 = "";
if (var4) {
var11 = " and i.uniqueness = 'UNIQUE'\n";
}
String var12 = " and i.index_name = c.index_name\n and i.table_owner = c.table_owner\n and i.table_name = c.table_name\n and i.owner = c.index_owner\n";
String var13 = "order by non_unique, type, index_name, ordinal_position\n";
String var14 = var17 + var8 + "union\n" + var9 + var10 + var11 + var12 + var13;
var6.closeOnCompletion();
OracleResultSet var15 = (OracleResultSet)var6.executeQuery(var14);
return var15;
} else {
throw (SQLException)((SQLException)DatabaseError.createSqlException(68).fillInStackTrace());
}
}
断点发现,这里的OracleSql.isValidObjectName(var2)表达式为false,点进去看
public static boolean isValidObjectName(String var0) {
assert var0 != null && var0.length() > 0 : "name is null or empty";
return DATABASE_OBJECT_NAME_RULE.matcher(var0).matches();
}
继续往下走;
DATABASE_OBJECT_NAME_RULE = Pattern.compile(""[^\"\\u0000]+"|\p{L}[\p{L}\p{N}_$#@]*");
再到这里,发现了一个正则表达式。于是可以看到,官网提到的初始化数据库的名称,在oracle的环境下,不符合jdbc的规则。
导致了程序在启动的时候无法访问数据库里面的数据,然后就启动不了了。于是我将对应的用户名进行了修改。
再进行启动,需要配置主键自增。然后整个server服务就没有问题了。
CREATE SEQUENCE native
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 9999999999999999999
NOORDER
NOCACHE
NOCYCLE;