hibernate - 为什么在将记录插入表时休眠不为主键列选择数据库序列?
问题描述
我在搞乱我的 Spring Boot 应用程序。编写了一些代码将少量记录插入到我的 h2 数据库中的表(称为 STARS)中。
这是它的schema.sql:
DROP TABLE IF EXISTS STAR;
CREATE TABLE STARS(
ID INT AUTO_INCREMENT PRIMARY KEY,
FIRST_NAME VARCHAR(25) NOT NULL,
LAST_NAME VARCHAR(25) NOT NULL
);
--STAR Sequence
drop sequence if exists STAR_SEQ;
create sequence STAR_SEQ
start with 500
increment by 100
minvalue 0
maxvalue 1000
nocycle;
实体类
package com.test.api.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.GeneratorType;
@Entity
@Table(name="star")
public class Star {
@Id
@SequenceGenerator(name="SEQ",sequenceName="STAR_SEQ",allocationSize=100)
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="SEQ")
private Long id;
private String first_name;
private String last_name;
public Star() {}
public Star(String first_name,String last_name) {
this.first_name=first_name;
this.last_name=last_name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
}
应用程序属性
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
server.port=8081
spring.h2.console.enabled=true
spring.h2.console.path=/h2
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
SpringBootApplication.java
package com.test.api;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.test.api.model.Star;
import com.test.api.service.StarsService;
@SpringBootApplication
public class SpringbootapiApplication implements CommandLineRunner{
@Autowired
StarsService starService;
public static void main(String[] args) {
SpringApplication.run(SpringbootapiApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
starService.saveStar(new Star("Morgan","Freeman"));
starService.saveStar(new Star("Brad","Pitt"));
starService.saveStar(new Star("Tom","Cruise"));
List<Star> allStars = starService.getAllStars();
System.out.println("Size of elements:"+allStars.size());
for(Star star:allStars)
System.out.println(star.getFirst_name()+":"+star.getLast_name()+":"+star.getId());
}
}
服务器启动日志
Hibernate: drop table star if exists
Hibernate: drop sequence if exists star_seq
Hibernate: create sequence star_seq start with 1 increment by 100
Hibernate: create table star (id bigint not null, first_name varchar(255), last_name varchar(255), primary key (id))
2019-11-16 23:43:19.733 INFO 13228 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2019-11-16 23:43:19.747 INFO 13228 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2019-11-16 23:43:20.245 WARN 13228 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-11-16 23:43:20.533 INFO 13228 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-11-16 23:43:20.957 INFO 13228 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2019-11-16 23:43:20.961 INFO 13228 --- [ main] com.test.api.SpringbootapiApplication : Started SpringbootapiApplication in 6.785 seconds (JVM running for 8.566)
Hibernate: call next value for star_seq
Hibernate: call next value for star_seq
Hibernate: insert into star (first_name, last_name, id) values (?, ?, ?)
Hibernate: insert into star (first_name, last_name, id) values (?, ?, ?)
Hibernate: insert into star (first_name, last_name, id) values (?, ?, ?)
Hibernate: select star0_.id as id1_0_, star0_.first_name as first_na2_0_, star0_.last_name as last_nam3_0_ from star star0_
Size of elements:3
Morgan:Freeman:1
Brad:Pitt:2
Tom:Cruise:3
我期待 db 序列被拾取,日志应该像这样打印:
Morgan:Freeman:500
Brad:Pitt:600
Tom:Cruise:700
请帮我理解。谢谢。
解决方案
我已将 spring.jpa.hibernate.ddl-auto 的值设置为 create-drop。这意味着休眠将使用实体定义为我创建模式。它根本没有考虑 schema.sql 文件。它只是使用实体类本身给出的配置来创建序列。为了让我的表从序列中检索 id。我只是将 spring.jpa.hibernate.ddl-auto 的值关闭为 none。这将使 schema.sql 在不休眠生成任何数据库对象(如表/序列)的情况下执行。
推荐阅读
- windows - 从 linux 的 powershell 调用命令获取退出代码
- python - 在python中优化指数曲线拟合
- php - 如何在 Laravel 中创建插件系统
- docker - Yaws 中的重定向在 docker 堆栈中做了什么?
- sqlalchemy - 如何在不更改数据库的情况下获取默认约束名称?
- kubernetes - AKS 元数据的区域信息存在差异
- php - 找不到.php时htacces错误的配置
- sql - SQL 查找每个国家的 2 个最高分
- c# - 在 Visual Studio 中将本地项目重新同步到 GitHub 存储库
- c++ - 如何调试从 C++ 调用的 rust 静态库