Hibernate JPA无法生成数据库Schema脚本问题求助
问题描述
我已配置jakarta.persistence.schema-generation.scripts.create-target属性以生成指定文件名的SQL脚本,但在MacOS上使用find命令搜索整个主目录后,未找到该文件。尝试过foo.sql、./foo.sql和/tmp/foo.sql三种路径,主目录和/tmp目录中均无结果。数据库表确实已创建,且运行日志中无报错信息。
相关代码文件
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="foo"> <class>Foo</class> <properties> <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql:///main" /> <property name="jakarta.persistence.jdbc.user" value="main" /> <property name="jakarta.persistence.jdbc.password" value="big1704cloudmain" /> <property name="hibernate.default_schema" value="foo" /> <property name="jakarta.persistence.schema-generation.database.action" value="validate" /> <property name="jakarta.persistence.schema-generation.scripts.create-target" value="foo.sql" /> </properties> </persistence-unit> </persistence>
Main.kt
import jakarta.persistence.Entity import jakarta.persistence.Id import jakarta.persistence.Persistence @Entity data class Foo (@Id val n: Int) fun main() { Persistence.createEntityManagerFactory("foo") println("Hello World!") }
build.gradle.kts
plugins { kotlin("jvm") version "latest.release" application } repositories { mavenCentral() } dependencies { implementation("org.postgresql:postgresql:latest.release") implementation("org.hibernate:hibernate-core:latest.release") } application { mainClass.set("MainKt") } java { toolchain { languageVersion.set(JavaLanguageVersion.of(18)) } }
运行输出
3:15:36 PM: Executing 'run'... > Task :compileKotlin UP-TO-DATE > Task :compileJava NO-SOURCE > Task :processResources UP-TO-DATE > Task :classes UP-TO-DATE > Task :run Hello World! BUILD SUCCESSFUL in 737ms 3 actionable tasks: 1 executed, 2 up-to-date May 13, 2023 3:15:36 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [name: foo] May 13, 2023 3:15:36 PM org.hibernate.Version logVersion INFO: HHH000412: Hibernate ORM core version 6.2.2.Final May 13, 2023 3:15:36 PM org.hibernate.cfg.Environment <clinit> INFO: HHH000406: Using bytecode reflection optimizer May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure WARN: HHH10001002: Using built-in connection pool (not intended for production use) May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001005: Loaded JDBC driver class: org.postgresql.Driver May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001012: Connecting with JDBC URL [jdbc:postgresql:///main] May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001001: Connection properties: {password=****, user=main} May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001003: Autocommit mode: false May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init> INFO: HHH10001115: Connection pool size: 20 (min=1) May 13, 2023 3:15:36 PM org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl logSelectedDialect INFO: HHH035001: Using dialect: org.hibernate.dialect.PostgreSQLDialect, version: org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$DialectResolutionInfoImpl@72ade7e3 May 13, 2023 3:15:36 PM org.hibernate.bytecode.internal.BytecodeProviderInitiator buildBytecodeProvider INFO: HHH000021: Bytecode provider name : bytebuddy May 13, 2023 3:15:36 PM org.hibernate.metamodel.internal.EntityInstantiatorPojoStandard resolveConstructor INFO: HHH000182: No default (no-argument) constructor for class: Foo (class must be instantiated by Interceptor) May 13, 2023 3:15:36 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] May 13, 2023 3:15:36 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@7ff35a3f] 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. 3:15:36 PM: Execution finished 'run'.
问题原因及解决办法
核心原因
你设置的jakarta.persistence.schema-generation.database.action属性值为validate,这个模式下Hibernate仅会验证数据库现有结构与实体类定义是否匹配,不会执行创建表的DDL操作,因此也不会生成对应的创建脚本。你提到数据库表已存在,大概率是之前其他操作(比如曾经设置过create模式)生成的,本次运行只是验证步骤。
解决步骤
修改DDL执行模式
将persistence.xml中的jakarta.persistence.schema-generation.database.action值改为create或create-drop:<property name="jakarta.persistence.schema-generation.database.action" value="create" />create:每次启动时创建表,若表已存在则覆盖create-drop:启动时创建表,关闭EntityManagerFactory时删除表
确认脚本生成路径
- 若使用相对路径(如
foo.sql),脚本默认生成在项目根目录(即执行./gradlew run的目录),而非用户主目录,直接去项目根目录查找即可。 - 若需要指定绝对路径,可直接写全路径,比如:
<property name="jakarta.persistence.schema-generation.scripts.create-target" value="/Users/你的用户名/foo.sql" />
- 若使用相对路径(如
内容的提问来源于stack exchange,提问作者user2297550
相关产品推荐
相关产品推荐

