在 Spring Boot JPA 中,为什么我会得到“表已经存在;SQL 语句:”

ds3*_*90s 6 java spring hibernate jpa spring-boot

我正在使用 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`)
);
Run Code Online (Sandbox Code Playgroud)

通过将数据库 URL 设置为DB_URL=jdbc:h2:mem:data360;INIT=RUNSCRIPT FROM 'classpath:schema.sql';DATABASE_TO_UPPER=false,schema.sql 被连接到初始化数据库,我已经验证这是正常工作。

在 my 中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]
Run Code Online (Sandbox Code Playgroud)

该错误清楚地表明某些东西正试图再次生成表。

会是什么呢?

有趣的是,如果我使用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;

...
Run Code Online (Sandbox Code Playgroud)

[/编辑]

win*_*ter 4

可能您的数据库仍在内存中,这就是您收到此错误的原因。我提出两种选择:

  1. 更改 SQL 语句。而不是CREATE TABLE config_user_preset...你可以使用CREATE TABLE IF NOT EXISTS config_user_preset ...
  2. 如果您使用 Spring,则可以创建嵌入式数据库。检查此处Spring embeddeb db 表已存在错误