我们的 Oracle 11g 数据库包含 298 个表(最近添加了 10 个),(+100 个序列),我们声明了 500 个游标。
当启动我们的 WebApplication(Tomcat 7.0,jdbc 池)时,在 sessionFactory 初始化时,hibernate 验证模式时它使用所有游标(参见下面)。
有什么已知的东西可以让 hibernate 对 Oracle 游标不那么贪婪吗?
请注意,此问题与处理准备好的语句或 hibernate 实体无关,因为我在这一步没有使用它们中的任何一个。
Caused by: org.hibernate.exception.GenericJDBCException: could not get table metadata: MYTABLE
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
at org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(DatabaseMetadata.java:105)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1080)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:116)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:317)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1300)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:863)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:782)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1573)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1511)
... 34 more
Caused by: java.sql.SQLException: ORA-01000: maximum open cursors exceeded
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:774)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:925)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1111)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:4845)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1501)
at oracle.jdbc.driver.OracleDatabaseMetaData.getColumnsWithWildcards(OracleDatabaseMetaData.java:350)
at oracle.jdbc.driver.OracleDatabaseMetaData.getColumns(OracleDatabaseMetaData.java:128)
at org.hibernate.tool.hbm2ddl.TableMetadata.initColumns(TableMetadata.java:146)
at org.hibernate.tool.hbm2ddl.TableMetadata.<init>(TableMetadata.java:32)
at org.hibernate.tool.hbm2ddl.DatabaseMetadata.getTableMetadata(DatabaseMetadata.java:90)
... 44 more
最佳答案
如果您的驱动程序版本是 12.1.0.2 那么这是一个已知错误:
https://community.oracle.com/thread/3682300
简而言之:DatabaseMetaData.getTableTypes()
创建一个 Statement
但从不关闭它,它使游标保持打开状态。
很可能 Hibernate 在模式验证期间经常调用 getTableTypes()
,因此您会受到此错误的影响。
驱动程序版本 12.1.0.1 不受此影响,因此您可能需要降级。
这记录在 Bug #19632480 下,因此如果您有权访问 MOS,则可以为此下载补丁。
关于java - 超过最大打开游标 - 使用 hibernate SchemaValidator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35227994/