【发布时间】:2018-09-22 00:20:45
【问题描述】:
我正在使用 JPA 存储库构建一个 Spring Boot 项目。对于测试,我使用 H2 内存数据库。我用一个schema.sql文件初始化数据库,摘录如下:
CREATE TABLE `config_user_preset_dataclass` (
`user_preset_dataclass_id` int(11) NOT NULL AUTO_INCREMENT,
`user_preset_id` int(11) NOT NULL,
`dataclass_name` varchar(100) NOT NULL,
`ngdp_audit_timestamp` datetime NOT NULL,
`ngdp_update_timestamp` datetime NOT NULL,
PRIMARY KEY (`user_preset_dataclass_id`),
UNIQUE KEY `idx_config_user_preset_dataclass_1` (`user_preset_id`,`dataclass_name`),
CONSTRAINT `fk_config_user_preset_dataclass_1` FOREIGN KEY (`user_preset_id`) REFERENCES `config_user_preset` (`user_preset_id`)
);
通过将数据库 URL 设置为 DB_URL=jdbc:h2:mem:data360;INIT=RUNSCRIPT FROM 'classpath:schema.sql';DATABASE_TO_UPPER=false 来连接 schema.sql 以初始化数据库,并且我已经验证这是正常的。
在我的src/test/resources/application.properties 中,我设置了spring.jpa.hibernate.ddl-auto=validate,因此不应该有任何二次尝试来生成表。但是,当我运行一个简单的测试来保存 JPA 模型时,我得到:
2018-04-11 17:59:17.847 ERROR 11540 --- [o-auto-1-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : Table "CONFIG_USER_PRESET" already exists; SQL statement:
CREATE TABLE `config_user_preset` (
`user_preset_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(6) NOT NULL,
`preset_name` varchar(200) NOT NULL,
`ngdp_audit_timestamp` datetime NOT NULL,
`ngdp_update_timestamp` datetime NOT NULL,
PRIMARY KEY (`user_preset_id`),
UNIQUE KEY `idx_user_preset_config_1` (`user_id`,`preset_name`)
) [42101-196]
错误清楚地表明某些东西正在尝试再次生成表。
会是什么?
有趣的是,如果我使用 GenerationType.IDENTITY 作为主键,这个错误就会消失。但是,这会导致另一个问题,所以我不能这样做。
[编辑]
@Entity
@Table(name = "config_user_preset_dataclass")
public class UserPresetDataclass {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_preset_dataclass_id")
private long presetDataClassId;
@Column(name = "user_preset_id")
private long userPresetId;
@Column(name = "dataclass_name")
private String dataclassName;
...
[/编辑]
【问题讨论】:
-
SpringBoot 有一个复杂的机制来检查数据库的类型、hibernate/jpa 属性等,并决定是否使用 sql 脚本初始化数据库。我们只需要配置 spring.datasource.initialization-mode 就可以了。只是想知道为什么要使用 INIT=RUNSCRIPT FROM 'classpath:schema.sql' 而不是使用开箱即用的功能?
-
在您的
src/main/resources/application.properties中您的属性spring.jpa.hibernate.ddl-auto是否设置为update? -
我正在使用 INIT=RUNSCRIPT 的东西,因为初始化模式不起作用,开箱即用的东西也不起作用。我公司糟糕的弹簧靴包装中可能有什么东西破坏了它。
-
我遇到了同样的问题(schema.sql 执行了两次),我刚刚做了一个 Maven 更新,错误就消失了。
标签: java spring hibernate spring-boot jpa