Java 带有 Hibernate 的 Spring Boot 在使用 H2 数据库启动时生成删除约束错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24727610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:31:09  来源:igfitidea点击:

Spring Boot with Hibernate generating drop constraint errors on startup with H2 database

javaspringhibernatejpah2

提问by Aaron Zeckoski

I am using spring-boot and have an H2 database configured like so (in the application.properties).

我正在使用 spring-boot 并且有一个像这样配置的 H2 数据库(在 application.properties 中)。

spring.datasource.url=jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

In the logs I am seeing the following errors:

在日志中,我看到以下错误:

o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
        name: default
        ...]
org.hibernate.Version                    : HHH000412: Hibernate Core {4.3.5.Final}
org.hibernate.cfg.Environment            : HHH000206: hibernate.properties not found
org.hibernate.cfg.Environment            : HHH000021: Bytecode provider name : javassist
o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
o.h.h.i.ast.ASTQueryTranslatorFactory    : HHH000397: Using ASTQueryTranslatorFactory
org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000389: Unsuccessful: alter table key_request drop constraint FK_53shrbc21c25inskpp1yoxxss if exists
org.hibernate.tool.hbm2ddl.SchemaExport  : Table "KEY_REQUEST" not found; SQL statement:
    alter table key_request drop constraint FK_53shrbc21c25inskpp1yoxxss if exists [42102-178]

Even though hibernate reports these as errors, I can then login to the H2 console and see the constraints and they appear to be just fine.

即使 hibernate 将这些报告为错误,我也可以登录到 H2 控制台并查看约束,它们似乎很好。

SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, INDEX_TYPE_NAME FROM information_schema.indexes WHERE TABLE_NAME='KEY_REQUEST';
TABLE_NAME    INDEX_NAME                            COLUMN_NAME  INDEX_TYPE_NAME  
KEY_REQUEST   PRIMARY_KEY_F                         REQUEST_ID   PRIMARY KEY
KEY_REQUEST   FK_53SHRBC21C25INSKPP1YOXXSS_INDEX_F  USER_ID      INDEX

If really looks like hibernate is trying to drop these constraints before it actually creates the database (i.e. some kind of bug in hibernate). Is there any way to avoid these errors clogging up the logs or are the indicative of a real failure somewhere?

如果真的看起来像 hibernate 试图在它实际创建数据库之前删除这些约束(即 hibernate 中的某种错误)。有什么方法可以避免这些错误堵塞日志或指示某处真正的故障?

UPDATE 1

更新 1

Trying to force the application to only do updates using this setting:

尝试强制应用程序仅使用此设置进行更新:

spring.jpa.hibernate.ddl-auto=update

Results in the following errors (all the other errors disappear):

导致以下错误(所有其他错误消失):

org.hibernate.tool.hbm2ddl.SchemaUpdate  : HHH000388: Unsuccessful: alter table lti_result add constraint FK_1cnh9amy5br8owkmafsrth3as foreign key (result_id) references lti_link
org.hibernate.tool.hbm2ddl.SchemaUpdate  : Constraint "FK_1CNH9AMY5BR8OWKMAFSRTH3AS" already exists; SQL statement: 
    alter table lti_result add constraint FK_1cnh9amy5br8owkmafsrth3as foreign key (result_id) references lti_link [90045-178]

NOTE: the source is here: https://github.com/azeckoski/lti_starter

注意:来源在这里:https: //github.com/azeckoski/lti_starter

Specifically the config: https://github.com/azeckoski/lti_starter/blob/master/src/main/resources/application.properties

特别是配置:https: //github.com/azeckoski/lti_starter/blob/master/src/main/resources/application.properties

and the model: https://github.com/azeckoski/lti_starter/tree/master/src/main/java/ltistarter/model

和模型:https: //github.com/azeckoski/lti_starter/tree/master/src/main/java/ltistarter/model

回答by Vlad Mihalcea

Because you are using an in-memory database, Hibernate won't find any table when executing:

因为您使用的是内存数据库,所以 Hibernate 在执行时不会找到任何表:

hibernate.hbm2ddl.auto=create-drop

That's because the statements order is:

那是因为语句顺序是:

  • drop the constraints (fk)
  • drop the tables
  • create the tables
  • create constraints (fk)

    Query:{[alter table tableIdentifier drop constraint FK_202gbutq8qbxk0chvcpjsv6vn][]} 
    ERROR [main]: o.h.t.h.SchemaExport - HHH000389: Unsuccessful: alter table tableIdentifier drop constraint FK_202gbutq8qbxk0chvcpjsv6vn
    ERROR [main]: o.h.t.h.SchemaExport - user lacks privilege or object not found: PUBLIC.TABLEIDENTIFIER
    Query:{[drop table sequenceIdentifier if exists][]} 
    Query:{[drop table tableIdentifier if exists][]} 
    Query:{[create table sequenceIdentifier (id bigint not null, primary key (id))][]} 
    Query:{[create table tableIdentifier (id bigint not null, sequenceIdentifier_id bigint, primary key (id))][]} 
    Query:{[alter table tableIdentifier add constraint FK_202gbutq8qbxk0chvcpjsv6vn foreign key (sequenceIdentifier_id) references sequenceIdentifier][]} 
    Query:{[create sequence hibernate_sequence start with 1 increment by 1][]} 
    
  • 删除约束(fk)
  • 放下桌子
  • 创建表
  • 创建约束(fk)

    Query:{[alter table tableIdentifier drop constraint FK_202gbutq8qbxk0chvcpjsv6vn][]} 
    ERROR [main]: o.h.t.h.SchemaExport - HHH000389: Unsuccessful: alter table tableIdentifier drop constraint FK_202gbutq8qbxk0chvcpjsv6vn
    ERROR [main]: o.h.t.h.SchemaExport - user lacks privilege or object not found: PUBLIC.TABLEIDENTIFIER
    Query:{[drop table sequenceIdentifier if exists][]} 
    Query:{[drop table tableIdentifier if exists][]} 
    Query:{[create table sequenceIdentifier (id bigint not null, primary key (id))][]} 
    Query:{[create table tableIdentifier (id bigint not null, sequenceIdentifier_id bigint, primary key (id))][]} 
    Query:{[alter table tableIdentifier add constraint FK_202gbutq8qbxk0chvcpjsv6vn foreign key (sequenceIdentifier_id) references sequenceIdentifier][]} 
    Query:{[create sequence hibernate_sequence start with 1 increment by 1][]} 
    

You can fix this by changing the hibernate.hbm2ddl.auto to update:

您可以通过将 hibernate.hbm2ddl.auto 更改为更新来解决此问题:

hibernate.hbm2ddl.auto=update

回答by user1470687

thanks, this work for me .

谢谢,这对我有用。

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto=create
logging.level.org.hibernate.SQL= DEBUG
hibernate.hbm2ddl.auto=update

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
# Enable response compression
server.compression.enabled=true
# The comma-separated list of mime types that should be compressed
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
# Compress the response only if the response size is at least 1KB
server.compression.min-response-size=1024
server.http2.enabled=true
# Maximum time the response should be cached (in seconds)
spring.resources.cache.cachecontrol.max-age=120
# The cache must re-validate stale resources with the server. Any expired resources must not be used without re-validating.
spring.resources.cache.cachecontrol.must-revalidate=true
#https://www.callicoder.com/configuring-spring-boot-application/
server.port=8080

回答by Sergey Ponomarev

Try create-only:

尝试create-only

spring.jpa.properties.hibernate.hbm2ddl.auto=create-only

It was added into Hibernate at least starting from 5.2 (maybe even earlier) and I didn't find any proper documentation but it mentioned User Guide: 23.15. Automatic schema generation

它至少从 5.2(甚至更早)开始被添加到 Hibernate 中,我没有找到任何合适的文档,但它提到了用户指南:23.15。自动模式生成

Also if you see in logs:

此外,如果您在日志中看到:

WARN  SessionFactoryOptionsBuilder:394 - Unrecognized hbm2ddl_auto value : create-only.  Supported values include 'create', 'create-drop', 'update', 'none' and 'validate'.  Ignoring

That's may be a false alarm and in fact it works

这可能是误报,实际上它有效