如何解决如何将Entity对象保存到带有生成索引的初始化h2表中?
我有一个带有h2数据库的spring boot项目。表debug
从schema.sql
初始化:
DROP TABLE IF EXISTS debug;
CREATE TABLE debug (
id BIGINT PRIMARY KEY,dummycol VARCHAR(250) NOT NULL
);
data.sql
:
INSERT INTO debug (id,dummycol) VALUES
(0,'foo'),(1,'ba');
为此,我必须将spring.jpa.hibernate.ddl-auto=none
放在application.properties中。根据{{3}},这对于schema.sql
是必要的,但是我发现在生成模式时(我假设从带注释的类中),使用诸如create-drop
之类的另一个值,加载脚本{{1 }}被忽略,因此启动后表为空。
我定义一个Entity类:
data.sql
然后,我将@Entity
@Table(name = "debug")
@Data
@NoArgsConstructor
public class DebugE {
@Id
//@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
private Long id;
@Column(name="dummycol")
private String dummy;
}
子类化:CrudRepository
并将实体对象添加到表中
public interface DebugRepository extends CrudRepository<DebugE,Long>
到目前为止,一切正常,但是现在我想@Autowired
DebugRepository cr;
...
DebugE d = new DebugE();
d.setId(computeFreeId(cr))
d.setDummy("foo1");
cr.save(d);
被自动设置。
为此,我将id
添加到类中并注释掉@GeneratedValue
,因为我希望框架能够为我做这件事。我对d.setId
没有偏好,到目前为止都行不通:GenerationType
,AUTO
:
SEQUENCE
o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 90036,SQLState: 90036
o.h.engine.jdbc.spi.SqlExceptionHelper : Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-200]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [call next value for hibernate_sequence]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement] with root cause
org.h2.jdbc.JdbcSQLSyntaxErrorException: Sequence "HIBERNATE_SEQUENCE" not found; SQL statement:
call next value for hibernate_sequence [90036-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:576) ~[h2-1.4.200.jar:1.4.200]
:
IDENTITY
o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23502,SQLState: 23502
o.h.engine.jdbc.spi.SqlExceptionHelper : NULL not allowed for column "ID"; SQL statement:
insert into debug (id,dummycol) values (null,?) [23502-200]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "ID"; SQL statement:
insert into debug (id,?) [23502-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:459) ~[h2-1.4.200.jar:1.4.200]
:
TABLE
基于其他问题的尝试:
- documentation
o.hibernate.id.enhanced.TableGenerator : HHH000351: Could not read or init a hi value org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "HIBERNATE_SEQUENCES" not found; SQL statement: select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update [42102-200] at org.h2.message.DbException.getJdbcSQLException(DbException.java:453) ~[h2-1.4.200.jar:1.4.200]
并将strategy=GenerationType.IDENTITY
添加到hibernate.dialect=org.hibernate.dialect.H2Dialect
。 发出警告:application.properties
,并且错误消息未更改 - https://stackoverflow.com/a/39094773
添加
'hibernate.dialect' is an unknown property.
spring.jpa.hibernate.use-new-id-generator-mappings=false
,IDENTITY
不变。SEQUENCE
的类似错误:
TABLE
- https://stackoverflow.com/a/63775719/3014199
将org.hibernate.orm.deprecation : HHH90000015: Found use of deprecated [org.hibernate.id.MultipleHiLoPerTableGenerator] table-based id generator; use org.hibernate.id.enhanced.TableGenerator instead. See Hibernate Domain Model Mapping Guide for details. o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 42102,SQLState: 42S02 o.h.engine.jdbc.spi.SqlExceptionHelper : Table "HIBERNATE_SEQUENCES" not found; SQL statement: select sequence_next_hi_value from hibernate_sequences where sequence_name = 'debug' for update [42102-200]
从spring.jpa.hibernate.ddl-auto
设置为none
是可行的(即生成ID,将行添加到表),但是现在不再从create-drop
初始化表。
其他详细信息
data.sql
:
application.properties
spring.datasource.url=jdbc:h2:mem:h2db
spring.h2.console.enabled=true
spring.h2.console.path=/h2
#spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.initialization-mode=embedded
#hibernate.dialect=org.hibernate.dialect.H2Dialect
#spring.jpa.hibernate.use-new-id-generator-mappings=false
:
build.gradle
解决方案
plugins {
id 'org.springframework.boot' version '2.3.3.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
id "io.freefair.lombok" version "5.2.1"
}
group = 'com.my.project'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
}
在application.properties中spring.jpa.hibernate.ddl-auto=none
在课堂上和
schema.sql中的@GeneratedValue(strategy=GenerationType.IDENTITY)
使它起作用。
解决方法
如果要同时使用* sql文件生成ID,则需要在创建表中的id字段中定义auto_increment属性。
由于使用生成策略-Identity时,hibernate认为列是表侧的自动增量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。