I have a pre-existing Postgres table designed to automatically generate a DEFAULT value for a UUID typed column THAT IS NOT THE PRIMARY KEY.
Here’s the DDL:
CREATE SEQUENCE IF NOT EXISTS uuid_column_table_seq;
CREATE TABLE IF NOT EXISTS uuid_column_table
(
uuid_column_table_id integer DEFAULT nextval('uuid_column_table_seq') NOT NULL,
not_pk_uuid uuid DEFAULT uuid_generate_v4() NOT NULL,
label text,
PRIMARY KEY (uuid_column_table_id)
);
And I have a JPA entity (I’m attempting) to match:
@Entity
@Table(name = "uuid_column_table")
public class UuidColumnTableEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer uuidColumnTableId;
@Column
@GeneratedValue
private UUID notPkUuid;
@Column
private String label;
public Integer getUuidColumnTableId() {
return this.uuidColumnTableId;
}
public void setUuidColumnTableId(Integer uuidColumnTableId) {
this.uuidColumnTableId = uuidColumnTableId;
}
public UUID getNotPkUuid() {
return this.notPkUuid;
}
public void setNotPkUuid(UUID notPkUuid) {
this.notPkUuid = notPkUuid;
}
public String getLabel() {
return this.label;
}
public void setLabel(String label) {
this.label = label;
}
}
When I execute the following code…
var uuidColumnTableEntity = new UuidColumnTableEntity();
uuidColumnTableEntity.setLabel("Test Label");
var uuidColumnTableEntityWithPk = UuidColumnTableEntityRepository.save(uuidColumnTableEntity);
…on the JPA repository of UuidColumnTableEntityRepository.save()
, I am getting an JPA exception of:
could not execute statement; SQL [n/a]; constraint [not_pk_uuid" of relation "uuid_column_table]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
Given I am unable to change the Postgres DDL definition, what do I need to correct in defining my JPA entity?
Versions:
- Java 17
- Spring Boot 2.5.6
- Jakarta Persistence 2.2.3
- Postgres 13.3
Note: I searched for some time hoping someone had a nearby answer to this. However, I found scads of questions and answers that are years out of date. And those closer in time were about how to get JPA to generate the value as opposed to reading back the value generated by the Postgres INSERT
.
2
Answers
Thanks to @Marco Belladielli's answer, I was FINALLY put on the right track to solve this.
tl;dr: Specifically...
@GeneratedValue
- With or without parameters, as it is used exclusive for the PK (Primary Key) generation@NotNull
- Even though the Postgres DDL explicitly shows the column asNOT NULL
@Generated(...)
- With specifically precise parameters@Column(...)
- Again, with specifically precise parametersDetails:
The only code changes is to the Entity's batchUuid property. This is what ended up working:
You can use Hibernate’s
@Generated
annotation, which indicates that the column you’re annotating is generated on the database side and will need to be retrieved after inserting new records with a subsequent select statement.JPA’s
@GeneratedValue
annotation is used to define primary key generation, as others have pointed out, and should not be used here.