Spring JPA + H2,脚本初始化数据库生成了额外的重复字段

我的表初始化结构和初始化数据是通过类路径的脚本生成导入的。如下图:

img


schema.sql 是表结构,data.sql 是数据。

这是表结构 schema.sql:

create table if not exists Ingredient(
    id varchar(4) not null primary key, 
    name varchar(50) not null, 
    type varchar(10) not null
);
create table if not exists Taco(
    id identity, 
    name varchar(50) not null, 
    createAt timestamp not null
);
create table if not exists Taco_Ingredients(
    taco bigint not null, 
    ingredient varchar(4) not null
);
alter table Taco_Ingredients add foreign key(taco) references Taco(id);
alter table Taco_Ingredients add foreign key(ingredient) references Ingredient(id);
create table if not exists Taco_Order(
    id identity, 
    deliveryName varchar(50) not null, 
    deliveryStreet varchar(50) not null, 
    deliveryCity varchar(50) not null, 
    deliveryState varchar(2) not null, 
    deliveryZip varchar(10) not null, 
    ccNumber varchar(16) not null, 
    ccExpiration varchar(5) not null, 
    ccCVV varchar(3) not null, 
    placeAt timestamp not null
);
create table if not exists Taco_Order_Tacos(
    tacoOrder bigint not null, 
    taco bigint not null
);
alter table Taco_Order_Tacos add foreign key(tacoOrder) references Taco_Order(id);
alter table Taco_Order_Tacos add foreign key(taco) references Taco(id);

create table if not exists User(
    id identity,
    username varchar(20), 
    password varchar(20), 
    fullname varchar(20), 
    street varchar(20), 
    city varchar(20), 
    state varchar(20), 
    zip varchar(20), 
    phoneNumber varchar(20)
);

这是数据 data.sql:

delete from Taco_Order_Tacos;
delete from Taco_Ingredients;
delete from Taco;
delete from Taco_Order;
delete from Ingredient;
delete from User;
insert into Ingredient (id, name, type) values('FALO', 'Flour Tortilla', 'WRAP');
insert into Ingredient (id, name, type) values('COTO', 'Corn Tortilla', 'WRAP');
insert into Ingredient (id, name, type) values('GRBF', 'Ground Beef', 'PROTEIN');
insert into Ingredient (id, name, type) values('CARN', 'Carnitas', 'PROTEIN');
insert into Ingredient (id, name, type) values('TMTO', 'Diced Tomatoes', 'VEGGIES');
insert into Ingredient (id, name, type) values('LETC', 'Lettuce', 'VEGGIES');
insert into Ingredient (id, name, type) values('CHED', 'Cheddar', 'CHEESE');
insert into Ingredient (id, name, type) values('JACK', 'Monterry Jack', 'CHEESE');
insert into Ingredient (id, name, type) values('SLSA', 'Salsa', 'SAUCE');
insert into Ingredient (id, name, type) values('SRCR', 'Sour Cream', 'SAUCE');
insert into User(username, password, fullname, street, city, state, zip, phoneNumber) values('buzz', 'infinity', 'a', 'a', 'a', 'a', 'a', 'a');
insert into User(username, password, fullname, street, city, state, zip, phoneNumber) values('woody', 'bullseye', 'b', 'b', 'b', 'b', 'b', 'b');

这是我的项目配置信息 application.properties:

spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.data-locations=classpath:data.sql

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

我遇到的问题是如下图,凡是脚本里是驼峰命名的,JPA 都给额外生成一个帕斯卡命名的字段。导致查询操作报错,我的 Spring Security 认证失败。

img

目前并没有什么线索可以排查,唯一知道的是,spring.jpa.hibernate.ddl-auto 取值 update 时,初始化的表结构才有数据,其他都没有数据。

看看实体类,@Column使用这个注解加上列名可不可以

这个问题我解决了,是配置的问题,归根结底是我对配置的误解。
先是解决生成重复字段的问题。我百度加上在 StackOverFlow 搜索 JPA 的字段生成方式,发现其实 JPA 的默认命名规则是“帕斯卡”命名,因而会把我的“驼峰”字段复制多一份“帕斯卡”字段,然后弃用“驼峰”字段。
可在 application.properties 通过如下属性设置,让 JPA 不生成新字段而使用旧字段。

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

然后解决数据为空的问题。是通过额外新建一个 SpringBoot 项目发现的,过程复杂。所以直接说解决办法,就是在 application.properties 加入如下设置:

spring.jpa.hibernate.ddl-auto=none

尽量抽时间写写发现过程吧。当作我在 CSDN 的初次尝试。