Skip to content

Instantly share code, notes, and snippets.

@itzg
Created March 3, 2024 20:25
Show Gist options
  • Save itzg/e8dad515dea51a607b1598046c4d9421 to your computer and use it in GitHub Desktop.
Save itzg/e8dad515dea51a607b1598046c4d9421 to your computer and use it in GitHub Desktop.
With Spring Data JDBC, error "cannot insert a non-DEFAULT value into column"

Problem

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.

Solution

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);
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment