With a PostgreSQL table created with a GENERATED ALWAYS AS IDENTITY
column:
CREATE TABLE activity
(
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
topic BIGINT REFERENCES topic (id) ON DELETE CASCADE,
name TEXT NOT NULL
);
and a Spring Data JDBC entity where the @Id
was left off of the id
field:
public record Activity(
Long id,
AggregateReference<Topic, Long> topic,
String name
) {
public static Activity create(Topic topic, String name) {
return new Activity(null, AggregateReference.to(topic.id()), name);
}
}
then a call to the CrudRepository.save
method will result in a slightly cryptic exception:
PreparedStatementCallback; bad SQL grammar [INSERT INTO "activity" ("id", "name", "topic") VALUES (?, ?, ?)]
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [INSERT INTO "activity" ("id", "name", "topic") VALUES (?, ?, ?)]
at app//org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:112)
at app//org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:107)
at app//org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:116)
at app//org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1548)
at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:677)
at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:970)
at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:991)
at app//org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:337)
at app//org.springframework.data.jdbc.core.convert.InsertStrategyFactory$DefaultInsertStrategy.execute(InsertStrategyFactory.java:96)
.
.
.
Caused by: org.postgresql.util.PSQLException: ERROR: cannot insert a non-DEFAULT value into column "id"
Detail: Column "id" is an identity column defined as GENERATED ALWAYS.
Hint: Use OVERRIDING SYSTEM VALUE to override.
Add @Id
(org.springframework.data.annotation.Id
) to the id
field:
public record Activity(
@Id
Long id,
AggregateReference<Topic, Long> topic,
String name
) {
public static Activity create(Topic topic, String name) {
return new Activity(null, AggregateReference.to(topic.id()), name);
}
}