Problems with id when saving data using Spring Data JPA Kotlin - spring

So when im trying to save data on a in memory H2 database with unit tests i get this following error. Saving works fine on normal postgres database. But im trying to make it work with H2 for unit tests.
> could not execute statement; SQL [n/a]; constraint [null]; nested
> exception is org.hibernate.exception.ConstraintViolationException:
> could not execute statement
This it the data class
#Entity
#Table(name = "delivery_type")
data class DeliveryType (
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", updatable = false, nullable = false)
val id: Long = 0,
#Column(name = "type")
val type: String,
)
Im trying to run a simple test
#SpringBootTest
#Transactional
internal class CarQueueServiceTest {
#Autowired
lateinit var deliveryTypeRepo: DeliveryTypeRepo
#Test
fun addDeliveryType() {
val deliveryType = DeliveryType(type = "Truck")
println(deliveryTypeRepo.save(deliveryType))
}
}
I will add some of the hibernate logs
Hibernate: create table delivery_type (id bigint generated by default as identity, type varchar(255), primary key (id))
Hibernate: insert into delivery_type (id, type) values (null, ?)
2022-03-21 11:36:00.656 TRACE 17340 --- [ Test worker] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [Truck]
2022-03-21 11:36:00.660 WARN 17340 --- [ Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23502, SQLState: 23502
2022-03-21 11:36:00.660 ERROR 17340 --- [ Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper : NULL not allowed for column "ID"; SQL statement:
insert into delivery_type (id, type) values (null, ?) [23502-210]
H2 setup
spring.h2.console.enabled=true
spring.h2.console.path=/h2_console
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto = create
spring.jpa.show-sql=true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

Related

Spring Data JDBC aggregate ID in child objects

I was playing with Spring-Data-JDBC and encountered 2 issues. I have following entities with 1:N relationship.
------
DROP TABLE IF EXISTS product;
CREATE TABLE product (
product_id int AUTO_INCREMENT PRIMARY KEY,
name varchar(250) not null,
description varchar(512) not null
);
DROP TABLE IF EXISTS product_line;
CREATE TABLE product_line (
product_id int constraint fk_product_line_product references product(product_id),
label varchar(250) not null
);
----------
#Data
#Builder
public class Product {
#Id
private Long productId;
private String name;
private String description;
#Singular
#MappedCollection(idColumn = "product_id", keyColumn = "product_id")
private Set<ProductLine> lines;
}
#Data
#Builder
public class ProductLine {
private Long productId;
private String label;
}
Problem 1: Following test case fails because I was expecting to have the productId populated in the ProductLine object but it is not. Is this the expected behavior of Spring Data JDBC?
#SpringBootTest
class SpringDataJdbcApplicationTests {
#Autowired
private ProductRepository productRepository;
#Test
void saveTest() {
Product product = Product.builder()
.name("Product-1")
.description("Description")
.line(ProductLine
.builder()
.label("Line-label")
.build())
.build();
this.productRepository.save(product);
assertThat(product.getProductId()).isNotNull();
assertThat(product.getLines()).isNotNull().isNotEmpty().hasSize(1);
assertThat(product.getLines().stream().findFirst()).isPresent();
assertThat(product.getLines().stream().findFirst().get().getProductId()).isNotNull().isEqualTo(product.getProductId()); // -----> Fails here.
}
}
Problem 2: If I change Set<ProductLine> to List<ProductLine>, it fails due to JdbcSQLIntegrityConstraintViolationException, which means the product id set to 0 as seen in the log snippet below.
2022-09-10 22:33:12.393 DEBUG 18460 --- [ main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [INSERT INTO "PRODUCT_LINE" ("LABEL", "PRODUCT_ID") VALUES (?, ?)]
2022-09-10 22:33:12.393 TRACE 18460 --- [ main] o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 1, parameter value [Line-label], value class [java.lang.String], SQL type 12
2022-09-10 22:33:12.393 TRACE 18460 --- [ main] o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 2, parameter value [0], value class [java.lang.Integer], SQL type 4
Following test case fails because I was expecting to have the productId populated in the ProductLine object but it is not. Is this the expected behavior of Spring Data JDBC?
Yes, if you want a productId you have to (and can easily) populate it yourself using plain Java code.
But you really shouldn't need the productId in the first place since if you follow Domain Driven Design, you will access a ProductLine exclusively from a Product which already has the id at hand.
The article https://spring.io/blog/2021/09/22/spring-data-jdbc-how-do-i-make-bidirectional-relationships might be helpful.
If I change Set<ProductLine> to List<ProductLine>, it fails due to JdbcSQLIntegrityConstraintViolationException, which means the product id set to 0 as seen in the log snippet below.
You have two problems here:
You already have two sources for the product_id field: The relation from the aggregate root and the simple field, which may cause problems.
You mapped both the back reference to the aggregate root idColumn and the index of the list keyColumn to the same database column. Together with the simple field from above these are three values all mapped to the same column. Not good.
The value that seems to win is the list index, resulting in the exception.
In order to fix that, create an additional column in the product_line table and map the list index to it.

org.hibernate.exception.ConstraintViolationException only during unit test, Cascade Delete not working

I have a Spring Kotlin project where I use JPA (Hibernate?) entities to map my database tables.
A Project is linked to multiple ProjectMaps. When a Project is deleted, I want all the ProjectMaps to be deleted also.
The DDL for my local H2 db is as follows.
CREATE TABLE IF NOT EXISTS "project" (
id INT AUTO_INCREMENT PRIMARY KEY,
other fields...
);
CREATE TABLE IF NOT EXISTS "project_map" (
project_id INT NOT NULL,
tag_id INT NOT NULL,
CONSTRAINT pk_project_id_tag_id PRIMARY KEY (project_id, tag_id),
CONSTRAINT fk_project_map_project_id
FOREIGN KEY (project_id) REFERENCES "project" (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT fk_project_map_tag_id
FOREIGN KEY (tag_id) REFERENCES "tag" (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
The entities are as follows.
Project
#Entity
#Table(name = "project")
class Project(
other fields...,
#JsonIgnore
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0,
) {
#JsonIgnore
#OneToMany(mappedBy = "projectMapId.project", cascade = [CascadeType.ALL], orphanRemoval = true)
val projectMaps = mutableSetOf<ProjectMap>()
}
ProjectMap
#Entity
#Table(name = "project_map")
class ProjectMap(
#EmbeddedId
var projectMapId: ProjectMapId,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ProjectMap) return false
if (projectMapId != other.projectMapId) return false
return true
}
override fun hashCode(): Int {
return projectMapId.hashCode()
}
}
#Embeddable
class ProjectMapId(
#ManyToOne
#JoinColumn(name = "project_id", nullable = false, referencedColumnName = "id")
var project: Project,
#ManyToOne
#JoinColumn(name = "tag_id", nullable = false, referencedColumnName = "id")
var tag: Tag,
) : Serializable {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is ProjectMapId) return false
if (project != other.project) return false
if (tag != other.tag) return false
return true
}
override fun hashCode(): Int {
var result = project.hashCode()
result = 31 * result + tag.hashCode()
return result
}
}
I have a ProjectRepository interface that extends JpaRepository. In my code somewhere I call projectRepo.deleteAllInBatch(projectsToBeDeleted), and when I run it I see that the ProjectMaps are indeed deleted together with the Projects. But when I write a unit test for that method, I get this error.
[main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions - Referential integrity constraint violation: "FKM2O7A1Y4HFNXYHQEYBQI9AABY: PUBLIC.PROJECT_MAP FOREIGN KEY(PROJECT_ID) REFERENCES PUBLIC.PROJECT(ID) (CAST(1 AS BIGINT))"; SQL statement:
delete from project where id=? [23503-210]
[main] ERROR com.dbs.localisemanagement.exception.RestExceptionHandler.handleAllUncaughtException - [L9y5j][500][1-Unknown] could not execute statement; SQL [n/a]; constraint ["FKM2O7A1Y4HFNXYHQEYBQI9AABY: PUBLIC.PROJECT_MAP FOREIGN KEY(PROJECT_ID) REFERENCES PUBLIC.PROJECT(ID) (CAST(1 AS BIGINT))"; SQL statement:
delete from project where id=? [23503-210]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["FKM2O7A1Y4HFNXYHQEYBQI9AABY: PUBLIC.PROJECT_MAP FOREIGN KEY(PROJECT_ID) REFERENCES PUBLIC.PROJECT(ID) (CAST(1 AS BIGINT))"; SQL statement:
delete from project where id=? [23503-210]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
The error is at this line projectRepo.deleteAllInBatch(projectsToBeDeleted), so I see that it is because there are still existing ProjectMaps that's why the Projects cannot be deleted.
I reckon it is because the Cascade Delete is not working during unit test, but I don't know why. Anyone has any idea on this?

Duplicate or Null error when trying to send POST request for JSON Object with Foreign Key using Spring JPA

Here's my parent entity:
#Entity(name = "DrivingInstructor")
#Table(name = "driving_instructor")
#Getter
#Setter
#NoArgsConstructor
public class DrivingInstructor {
#Id
#Column(name = "driving_instructor_id")
private long drivingInstructorId;
#Column(name = "driving_instructor_name")
#Size(max = 128)
private String drivingInstructorName;
#Column(name = "specialization")
#Size(max = 200)
private String specialisation;
}
And here's my supposed child entity:
#Entity(name = "DrivingStudent")
#Table(name = "driving_student")
#Getter
#Setter
#NoArgsConstructor
public class DrivingStudent {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "driving_student_id")
private long drivingStudentId;
#Column(name = "driving_student_name")
#Size(max = 128)
private String drivingStudentName;
#ManyToOne(cascade = CascadeType.ALL, targetEntity = DrivingInstructor.class)
#JoinColumn(name = "driving_instructor_id", referencedColumnName = "driving_instructor_name", insertable = false, updatable = false)
private DrivingInstructor drivingInstructor;
}
Here's the relevant chunk of my service class for inserting/saving an instance of a DrivingStudent into the database:
#RequestMapping(path = "api/v0/driving-school")
#RestController
#AllArgsConstructor
public class DrivingStudentRestController {
private final DrivingStudentServiceImpl drivingStudentServiceImpl;
#PostMapping
Long insertOrUpdateDrivingStudent(#Valid #RequestBody DrivingStudent drivingStudent) {
return drivingStudentServiceImpl.insertOrUpdateDrivingStudent(drivingStudent);
}
}
DrivingStudentServiceImpl is just an abstraction layer for Repository class that extends JpaRepository<DrivingStudent, Long>, so insertOrUpdateDrivingStudent() is practically just using the save() method from CrudRepository.
An instance of DrivingInstructor is already pre-inserted with drivingInstructorId of 1, and so I tried to execute a POST request via Postman using this JSON object:
{
"drivingStudentName": "Peter Parker",
"drivingInstructor": {"drivingInstructorId": 1}
}
And I'm getting this exception:
2021-08-27 20:03:37.554 ERROR 16108 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper :
ERROR: duplicate key value violates unique constraint "driving_instructor_pkey"
Detail: Key (driving_instructor_id)=(1) already exists.
2021-08-27 20:03:37.590 ERROR 16108 --- [nio-8080-exec-3] 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 [driving_instructor_pkey];
nested exception is org.hibernate.exception.ConstraintViolationException:
could not execute statement] with root cause
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "driving_instructor_pkey"
Detail: Key (driving_instructor_id)=(1) already exists.
I also tried revising my RestController's PostMapping to look like this, but still nothing changes:
#RequestMapping(path = "api/v0/driving-school")
#RestController
#AllArgsConstructor
public class DrivingStudentRestController {
private final DrivingInstructorRepository drivingInstructorRepository;
private final DrivingStudentServiceImpl drivingStudentServiceImpl;
#PostMapping
Long insertOrUpdateDrivingStudent(#Valid #RequestBody DrivingStudent drivingStudent) {
Optional<DrivingInstructor> drivingInstructor = drivingInstructorRepository.findById(drivingStudent.getDrivingInstructor().getDrivingInstructorId());
if (drivingInstructor.isPresent()) {
drivingStudent.setDrivingInstructor(drivingInstructor.get());
return drivingStudentServiceImpl.insertOrDrivingStudent(drivingStudent);
}
return null;
}
}
The error I am getting then changed to:
2021-08-27 21:36:58.622 ERROR 11388 --- [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper :
ERROR: null value in column "driving_instructor_number" of relation "driving_student" violates not-null constraint
Detail: Failing row contains (Peter Parker, null).
2021-08-27 21:36:58.632 ERROR 11388 --- [nio-8080-exec-4] 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 [driving_instructor_number" of relation "driving_student];
nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
org.postgresql.util.PSQLException: ERROR: null value in column "driving_instructor_number" of relation "driving_student" violates not-null constraint
Detail: Failing row contains (Peter Parker, null).
There are stuff I've tried but most exceptions simply end up with either of those two. All I really wanted to do was insert an instance of DrivingStudent into the database using POST request, with a foreign key connecting it to a DrivingInstructor instance, and then of course, be able to retrieve those data.
I am able to do insert data manually into the database using the statement:
INSERT INTO driving_student VALUES ('Peter Parker', 1);
And I am able to retrieve that data in JSON format using GET method. So far, my only problem really is how to deal with the POST method.
Ok, I just changed/simplified the annotations in DrivingStudent's drivingInstructor JoinColumn field from this:
#ManyToOne(cascade = CascadeType.ALL, targetEntity = DrivingInstructor.class)
#JoinColumn(name = "driving_instructor_id", referencedColumnName = "driving_instructor_name", insertable = false, updatable = false)
private DrivingInstructor drivingInstructor;
to this:
#ManyToOne
#JoinColumn(name = "driving_instructor_id")
private DrivingInstructor drivingInstructor;
and it somehow worked... I have no idea why though.

Hibernate insert fails - java.sql.SQLException: Invalid arguments in call

I'm trying to insert the user object to Oracle with Hibernate. Object is loaded with values entered in the user registration form.
id is #GeneratedValue
pass is #Transient
These are the properties of User and UserType classes:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 50, nullable = false)
#NotBlank(message = "Boş bırakılamaz.")
#Size(min=2, max = 50)
private String firstName;
#Column(length = 50, nullable = false)
#NotBlank(message = "Boş bırakılamaz.")
#Size(min=2, max = 50)
private String lastName;
#Column(length = 50, nullable = false)
#NotBlank(message = "Boş bırakılamaz.")
#Size(min=2, max = 50)
private String userName;
#Column(columnDefinition = "char(128)")
private String passHash;
#Column(columnDefinition = "char(32)")
private String salt;
#ManyToOne
#NotNull(message = "Boş bırakılamaz.")
private UserType userType;
#Transient
#NotBlank(message = "Boş bırakılamaz.")
#Size(min=4)
private String pass;
}
#Entity
public class UserType {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(length = 50, nullable = false)
#NotBlank(message = "Boş bırakılamaz.")
private String name;
}
This is the Oracle DDL:
create table DH_USER
(
ID NUMBER(19) generated as identity
primary key,
FIRSTNAME VARCHAR2(50 char) not null,
LASTNAME VARCHAR2(50 char) not null,
PASSHASH CHAR(128),
SALT CHAR(32),
USERNAME VARCHAR2(50 char) not null,
USERTYPE_ID NUMBER(19) not null
constraint FKO3DS41MXQLO527MM8H8J7F0FL
references DH_USERTYPE
)
create table DH_USERTYPE
(
ID NUMBER(19) generated as identity
primary key,
NAME VARCHAR2(50 char) not null
)
After adding logging.level.org.hibernate.SQL=DEBUG and logging.level.org.hibernate.type=TRACE to application.properties file, critical part of the log is now like this:
2020-12-08 15:41:59.256 INFO 6676 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2020-12-08 15:41:59.356 DEBUG 6676 --- [nio-8080-exec-2] org.hibernate.SQL : select usertype0_.id as id1_1_0_, usertype0_.name as name2_1_0_ from DH_UserType usertype0_ where usertype0_.id=?
Hibernate: select usertype0_.id as id1_1_0_, usertype0_.name as name2_1_0_ from DH_UserType usertype0_ where usertype0_.id=?
2020-12-08 15:41:59.379 TRACE 6676 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [2]
2020-12-08 15:41:59.481 TRACE 6676 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicExtractor : extracted value ([name2_1_0_] : [VARCHAR]) - [Yönetici]
2020-12-08 15:41:59.830 DEBUG 6676 --- [nio-8080-exec-2] org.hibernate.SQL : insert into DH_User (id, firstName, lastName, passHash, salt, userName, userType_id) values (default, ?, ?, ?, ?, ?, ?)
Hibernate: insert into DH_User (id, firstName, lastName, passHash, salt, userName, userType_id) values (default, ?, ?, ?, ?, ?, ?)
2020-12-08 15:41:59.834 WARN 6676 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 17068, SQLState: 99999
2020-12-08 15:41:59.834 ERROR 6676 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Invalid arguments in call
2020-12-08 15:41:59.863 ERROR 6676 --- [nio-8080-exec-2] 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.orm.jpa.JpaSystemException: could not prepare statement; nested exception is org.hibernate.exception.GenericJDBCException: could not prepare statement] with root cause
Why does Hibernate add the id field into the insert statement?
id field is "generated as identity" so doesn't need to be involved in the query.
And why does it try to insert "default" into id column? It should use null instead of default, as null is the value of user.id at that point in the code.
DH_User (id, firstName, lastName, passHash, salt, userName, userType_id) values (default, ?, ?, ?, ?, ?, ?)
Oracle should support the DEFAULT syntax, I've seen it being used like here: https://www.techrepublic.com/article/oracle-tip-how-to-use-default-values-with-database-columns/
Maybe there are different editions of Oracle and yours does not have support for this? Or maybe you need to use GENERATED BY DEFAULT AS IDENTITY? Anyway, you can override this by subclassing org.hibernate.dialect.identity.Oracle12cIdentityColumnSupport and org.hibernate.dialect.Oracle12cDialect which then has to return that subclass instance in getIdentityColumnSupport().
In a custom Oracle12cIdentityColumnSupport class you can also use null for getIdentityInsertString instead of default, but then make sure you also change getIdentityColumnString to use generated by default on null as identity.
By the way, I would recommend using sequences whenever possible for performance reasons. The use of sequences and sequence caching allows Hibernate to defer/reorder and batch inserts which will improve performance drastically when inserting a lot.
Changing the annotation of id field as
#GeneratedValue(strategy = GenerationType.SEQUENCE)
worked. But I don't understand why.
And I don't want to use a sequence. I want to use an auto-generated ID and get a value back post insertion.
I need an annotation resulting exactly:
GENERATED BY DEFAULT ON NULL AS IDENTITY
I tried to use the columnDefinition. You can see that "not null" is appended automatically even I use nullable = true.
As Christian suggested, I tried Oracle12cIdentityColumnSupport method and successfully changed Hibernate's way of generating IDENTITY ddl. But I got the same error, Invalid arguments in call :(
Seems like the only way for me is GenerationType.SEQUENCE
AFAIK, generated by default on null as identity is the least restrictive way of defining id columns and allowing null id's while inserting.

Import data at startup Spring boot

I'm trying to launch a SQL file at my database initialization.
Here is my configuration:
spring:
profiles: local
jpa:
properties:
hibernate.temp.use_jdbc_metadata_defaults: false
generate-ddl: true
hibernate:
ddl-auto: update
database: h2
show-sql: true
autoCommit: false
datasource:
platform: h2
url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;
driver-class-name: org.h2.Driver
initialization-mode: always
data: classpath:/sql/CreateGeographicZones.sql
My script is just this line (atm):
INSERT INTO GEOGRAPHIC_ZONE (name) VALUES ('EUROPE');
And the related entity:
#NoArgsConstructor
#Data
#Entity
#Table(name = "GEOGRAPHIC_ZONE")
public class GeographicZone {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "geo_zone_sequence")
#SequenceGenerator(name = "geo_zone_sequence", sequenceName = "geo_zone_id_seq", allocationSize = 1)
#Column(nullable = false)
private Long id;
...
}
The table is created as I can see in the logs:
Hibernate: create table geographic_zone (id bigint not null, name varchar(100) not null, primary key (id))
But I have an SQL error when the script is executed:
Table "GEOGRAPHIC_ZONE" not found; SQL statement:
INSERT INTO GEOGRAPHIC_ZONE (name) VALUES ('EUROPE')
In the logs I can see that my table is created before the script execution, so why it's not working ?
According with your entity's metadata Hibernate is querying geo_zone_id_seq sequence's next value and using it for the ID on each insert.
If you would like to use the same approach when inserting directly in your database then you will need to implement a H2 Trigger
Also you may use either the EntityManager bean or your Spring JPA Repository to insert your data after application startup via CommandLineRunner interface.
Using EntityManager:
#Bean
CommandLineRunner registerZonesDataRunner(EntityManager entityManager, TransactionTemplate transactionTemplate) {
return args -> transactionTemplate.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// presuming that GeographicZone has a constructor expecting NAME
Stream.of("AFRICA", "EUROPE")
.map(GeographicZone::new)
.forEach(entityManager::persist);
}
});
Using Spring JPA Repository:
#Bean
CommandLineRunner registerZonesDataRunner(GeographicZoneRepository repository) {
// presuming that GeographicZone has a constructor expecting NAME
return args -> repository.saveAll(Stream.of("AFRICA", "EUROPE")
.map(GeographicZone::new)
.collector(Collectors.toList()));
}
minimal, reproducible example
You don't show how you've defined the id column but the schema indicates there is no auto-generation scheme. So, try:
INSERT INTO GEOGRAPHIC_ZONE (id, name) VALUES (1, 'EUROPE');
in your data file. If that works, you'll need to either manually set the id in your inserts or add something like #GeneratedValue(strategy = AUTO) to your #Id property.

Resources