Hibernate: Caused by: java.sql.SQLException: Table/View 'USERS' 已经存在于 Schema 中

Hibernate: Caused by: java.sql.SQLException: Table/View 'USERS' already exists in Schema

我在 Java SE 8 上,我使用 Hibernate ORM 进行持久化。

休眠配置:

<property name="hibernate.dialect">org.hibernate.dialect.DerbyTenSevenDialect</property>
<property name="hibernate.hbm2ddl.auto">update</property><!-- update vs validate-->

持久性实体 Users DB table 具有以下键:

    @Id
    @Column(name = "email", nullable = false, unique = true, updatable = false)
    private String email = "";

当我启动应用程序时,我得到以下信息:

 May 23, 2019 10:53:16 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.4.2.Final}
May 23, 2019 10:53:17 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
May 23, 2019 10:53:17 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.DerbyTenSevenDialect
May 23, 2019 10:53:19 PM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
INFO: HHH000130: Instantiating explicit connection provider: org.hibernate.connection.C3P0ConnectionProvider
May 23, 2019 10:53:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH010002: C3P0 using driver: org.apache.derby.jdbc.EmbeddedDriver at URL: jdbc:derby:appName-v1.db;create=false;useSSL=false
May 23, 2019 10:53:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001001: Connection properties: {user=user, password=****}
May 23, 2019 10:53:19 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001003: Autocommit mode: false
May 23, 2019 10:53:19 PM com.mchange.v2.log.MLog 
INFO: MLog clients using java 1.4+ standard logging.
May 23, 2019 10:53:20 PM com.mchange.v2.c3p0.C3P0Registry 
INFO: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
May 23, 2019 10:53:20 PM org.hibernate.c3p0.internal.C3P0ConnectionProvider configure
INFO: HHH10001007: JDBC isolation level: <unknown>
May 23, 2019 10:53:20 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource 
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@c07c305b [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@36772381 [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 250, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceSynchronousCheckins -> false, identityToken -> 1hge17oa21s08ng61w9xxa8|40b5cb4d, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 60, maxStatementsPerConnection -> 0, minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@59324586 [ description -> null, driverClass -> null, factoryClassLocation -> null, forceUseNamedDriverClass -> false, identityToken -> 1hge17oa21s08ng61w9xxa8|73f7aa9e, jdbcUrl -> jdbc:derby:appName-v1.db;create=false;useSSL=false, properties -> {user=******, password=******} ], preferredTestQuery -> null, privilegeSpawnedThreads -> false, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, extensions -> {}, factoryClassLocation -> null, identityToken -> 1hge17oa21s08ng61w9xxa8|71ff733a, numHelperThreads -> 3 ]
May 23, 2019 10:53:22 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@72bcd19] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create table app.Users (email varchar(255) not null, pass varchar(255) not null, recoveryPhrase varchar(255) not null, salt varchar(255) not null, uuid varchar(255) not null, primary key (email))

然后我得到异常:

WARN: GenerationTarget encountered exception accepting command : Error executing DDL "create table app.Users (email varchar(255) not null, pass varchar(255) not null, recoveryPhrase varchar(255) not null, salt varchar(255) not null, uuid varchar(255) not null, primary key (email))" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table app.Users (email varchar(255) not null, pass varchar(255) not null, recoveryPhrase varchar(255) not null, salt varchar(255) not null, uuid varchar(255) not null, primary key (email))" via JDBC Statement
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:559)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:504)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.createTable(AbstractSchemaMigrator.java:277)
    at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:71)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:309)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
    at mr.m.v.dataBase.HibernateBOProcessor.<init>(HibernateBOProcessor.java:49)
    at mr.m.v.dataBase.HibernateBOProcessor.<clinit>(HibernateBOProcessor.java:28)
    at mr.m.v.security.authJaas.steady.DBLoginModule.login(DBLoginModule.java:87)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.invoke(Unknown Source)
    at javax.security.auth.login.LoginContext.access[=16=]0(Unknown Source)
    at javax.security.auth.login.LoginContext.run(Unknown Source)
    at javax.security.auth.login.LoginContext.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
    at javax.security.auth.login.LoginContext.login(Unknown Source)
    at mr.m.v.security.authJaas.JaasLoginContext.login(JaasLoginContext.java:103)
    at mr.m.v.gui.MainUI.lambda[=16=](MainUI.java:227)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.sql.SQLException: Table/View 'USERS' already exists in Schema 'app'.
    at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source)
    at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
    at com.mchange.v2.c3p0.impl.NewProxyStatement.execute(NewProxyStatement.java:75)
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
    ... 29 more
Caused by: ERROR X0Y32: Table/View 'USERS' already exists in Schema 'app'.
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
    at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.duplicateDescriptorException(Unknown Source)
    at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.addDescriptor(Unknown Source)
    at org.apache.derby.impl.sql.execute.CreateTableConstantAction.executeConstantAction(Unknown Source)
    at org.apache.derby.impl.sql.execute.MiscResultSet.open(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(Unknown Source)
    at org.apache.derby.impl.sql.GenericPreparedStatement.execute(Unknown Source)
    ... 34 more

Hibernate: alter table app.Users drop constraint UK_bnk3qe2j3b69p30frfqk2i76d
Hibernate: alter table app.Users add constraint UK_bnk3qe2j3b69p30frfqk2i76d unique (uuid)

我不喜欢它的一点是,它会在我每次启动应用程序时尝试重新创建数据库 table。 当 hibernate.hbm2ddl.auto 设置为 update 时,它会这样做。 如果我将它设置为 validate,Hibernate 会抱怨 DB table 不存在。 create 选项也不可行,它删除 table 并重新创建它。 所以,我想保留我已经创建的 DB tables。因此,我需要 updatevalidate 作为值。

在旧版本的 Hibernate 上,update 选项满足我的要求。

我想知道例外情况是否可能是 acceptable 结果。例如,在应用程序服务器上,如果用户身份验证失败,您会收到一个异常(在 IDE 的控制台上)作为身份验证失败的有效指示。仅举几例...

我已经找到解决方法。 看来解决方案是将 hibernate.hbm2ddl.auto 设置为 none。然后应用程序按预期运行,并进行数据库通信。即不尝试re-create table.

然而,如果 DB 没有 tables,并且您想在 run-time 处创建它们(使用 Hibernate),则可以将键设置为 更新。但是下次启动应用程序时,将密钥设置为 none,只要您希望系统创建的所有 table 都已经创建即可。