Spring Boot+H2数据库:添加实体类后SQL文件数据插入失败
问题描述
我尝试通过SQL文件向Spring Boot集成的H2数据库插入数据。将SQL文件放在src/main/resources目录时,能成功创建表并插入数据;但创建对应employees表的Employee实体类后,仅能创建表,无法插入数据。
相关代码
SQL文件
CREATE TABLE employees ( id INT AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(250) NOT NULL, last_name VARCHAR(250) NOT NULL, mail VARCHAR(250) NOT NULL, password VARCHAR(250) NOT NULL ); INSERT INTO employees (first_name, last_name, mail, password) VALUES ('Laurent', 'GINA', 'laurentgina@mail.com', 'laurent');
Employee实体类
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import lombok.Data; @Data @Entity @Table(name = "employees") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name="first_name") private String first_name; @Column(name="last_name") private String last_name; private String mail; private String password; }
application.properties配置
#Global configuration spring.application.name=api #Tomcat configuration server.port=9000 #Log level configuration logging.level.root=ERROR logging.level.com.openclassrooms=INFO logging.level.org.springframework.boot.autoconfigure.h2=INFO logging.level.org.springframework.boot.web.embedded.tomcat=INFO #H2 Configuration spring.h2.console.enabled=true
问题原因及解决方法
核心原因
当项目中存在JPA实体类时,Spring Boot默认会启用ddl-auto自动配置(默认值依版本不同为create-drop或update)。这会导致JPA先根据实体类生成表结构,你的SQL脚本执行时机被打乱:要么CREATE TABLE语句被JPA的表生成逻辑覆盖,要么INSERT语句在表结构未就绪时执行,最终导致数据插入失败。
具体解决步骤
延迟数据源初始化
在application.properties中添加以下配置,让SQL脚本在JPA完成表结构创建/更新后再执行:spring.jpa.defer-datasource-initialization=true控制ddl-auto行为
根据需求显式设置spring.jpa.hibernate.ddl-auto的值:- 若完全依赖自己的SQL文件建表,设置为
none:spring.jpa.hibernate.ddl-auto=none - 若需要JPA维护表结构同时执行插入脚本,设置为
update即可,配合上述延迟配置就能确保数据插入脚本在表就绪后执行。
- 若完全依赖自己的SQL文件建表,设置为
规范SQL脚本命名(可选)
Spring Boot默认自动执行schema.sql(建表)和data.sql(插数据),如果你的脚本文件名不是这两个,需显式指定路径:spring.sql.init.schema-locations=classpath:your-schema-file.sql spring.sql.init.data-locations=classpath:your-data-file.sql建议将建表和插数据逻辑拆分到两个文件,保证执行顺序。
额外注意事项
- 实体类中
id字段类型为Long,但SQL中定义为INT,虽然H2会自动兼容,但建议将SQL中的id INT改为id BIGINT,避免潜在类型转换问题。 - 确保SQL文件编码为UTF-8,避免特殊字符导致脚本执行失败。
内容的提问来源于stack exchange,提问作者mohamed abdelhamid elmansour
相关产品推荐
相关产品推荐

