我有一個帶有 h2 資料庫的 spring boot 專案。
我有一個要從中生成架構的物體類:
@NoArgsConstructor
@Entity
@Table(name = "NAMES")
public class Name {
@Id
@GeneratedValue
public Long id;
@Column(nullable = false)
public String name;
public Name(String name) {
this.name = name;
}
}
我有一個data.sql檔案:
insert into names (id, name) values (1, 'Alex');
insert into names (id, name) values (2, 'Bob');
我的 application.properties 是:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.defer-datasource-initialization=true
spring.jpa.show-sql=true
應用程式啟動得很好,我可以通過 localhost:8080/h2-console 確認資料已加載到資料庫中。但我無法將新資料保存到表中
//public interface NameRepository extends CrudRepository<Name,Long> {}
@RestController
@Service
public class MyController {
@Autowired
private final NameRepository nameRepository;
@PostMapping("/triggerError")
public ResponseEntity<Void> trigger() {
Name newName = new Name("Chris");
nameRepository.save(newName);
return ResponseEntity.ok().build();
}
}
錯誤資訊是:
could not execute statement; SQL [n/a]; constraint [\"PRIMARY KEY ON PUBLIC.NAMES(ID) ( /* key:1 */ CAST(1 AS BIGINT), 'Alex')\"; SQL statement:
insert into names (name, id) values (?, ?) [23505-210]];
我假設這意味著 spring 想要在 id=1 處插入新名稱,而沒有意識到 ids 1 和 2 已經在使用中。我想正確的引數@GeneratedValue可以解決它,但我不明白它們的含義以及選擇哪一個。
試驗和錯誤:
@GeneratedValue(strategy = GenerationType.AUTO)是默認值,見上文。
@GeneratedValue(strategy = GenerationType.TABLE)相同的錯誤
@GeneratedValue(strategy = GenerationType.SEQUENCE)相同的錯誤
@GeneratedValue(strategy = GenerationType.IDENTITY)不同的錯誤:
...
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column \"ID\"; SQL statement:\ninsert into names (id, name) values (null, ?) [23502-210]
...
could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
所以顯然它不是注釋,而是別的東西。
我放棄了,這是我的 MRE:https ://github.com/timo-a/duckpond-spring-backend/tree/debug/saving
uj5u.com熱心網友回復:
@Shankar Ghimire 部分正確。這既是 Hibernate 錯誤,也是 data.sql 問題。將您的 Hibernate 版本更新到 5.6.5:
implementation('org.springframework.boot:spring-boot-starter-data-jpa'){
exclude group: 'org.hibernate', module: 'hibernate-core'
}
implementation 'org.hibernate:hibernate-core:5.6.5.Final'
并且由于您使用的是 h2 auto_increment,因此您應該洗掉 data.sql 中的 id
insert into names (name)
values ('Alex'),('Bob');
序列不會增加,否則會導致唯一索引或主鍵違規。
順便說一句,您的存盤庫使用 Integer 作為您的 PK,而您的物體使用 Long。由于問題被標記為 JPA,請使用:
public interface NameRepository extends JpaRepository<Name,Long> {}
你在一個名為“scores”的表中插入資料,但我認為這是一個錯字。
uj5u.com熱心網友回復:
這是 hibernate 上的一個錯誤,特定于 h2 資料庫。 https://hibernate.atlassian.net/browse/HHH-14985
您可以使用id BIGINT GENERATED BY DEFAULT AS IDENTITY DEFAULT ON NULL PRIMARY KEY列定義作為修復。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "id BIGINT GENERATED BY DEFAULT AS IDENTITY DEFAULT ON NULL PRIMARY KEY")
private Long id;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/428670.html
