I\'m trying to persist an entity in PostgreSQL that uses UUID as primary key. I\'ve tried persisting it as a plain UUID:
@Id
@Column(name = \"customer_id\")
I am sure, that once you generated UUID for a record, it will be static. Thus there is no point in mapping UUID as an object to database and then converting it back to String on retrieval.
Use UUID as a String:
@Id
@Column(name = "customer_id")
private String id;
//getter and setter
public void setId(UUID id) {
this.id = id.toString();
}
Also there are some things to consider:
To have it working with Hibernate 5.1.x, you can follow Steve Ebersole comment here
@Id
@GeneratedValue
@Column( columnDefinition = "uuid", updatable = false )
public UUID getId() {
return id;
}
JPA 2.1 provides a very easy way to use the PostgreSQL uuid column type and java.util.UUID
as the type of the corresponding entity field:
@javax.persistence.Converter(autoApply = true)
public class PostgresUuidConverter implements AttributeConverter<UUID, UUID> {
@Override
public UUID convertToDatabaseColumn(UUID attribute) {
return attribute;
}
@Override
public UUID convertToEntityAttribute(UUID dbData) {
return dbData;
}
}
Just add this class to your persistence configuration and annotate UUID fields with @Column(columnDefinition="uuid")
.
Newer version >= 8.4-701
of Postgresql JDBC driver correctly handle java.util.UUID
mapping. And so do Hibernate >= 4.3.x
.
See details on https://stackoverflow.com/a/780922/173149:
Map the database uuid type to java.util.UUID.
This only works for relatively new server (8.3) and JDK (1.5) versions.
The PostgreSQL JDBC driver has chosen an unfortunately way to represent non-JDBC-standard type codes. They simply map all of them to Types.OTHER. Long story short, you need to enable a special Hibernate type mapping for handling UUID mappings (to columns of the postgres-specific uuid datatype):
@Id
@Column(name = "customer_id")
@org.hibernate.annotations.Type(type="org.hibernate.type.PostgresUUIDType")
private UUID id;
or more succinctly:
@Id
@Column(name = "customer_id")
@org.hibernate.annotations.Type(type="pg-uuid")
private UUID id;
Another (better) option is to register org.hibernate.type.PostgresUUIDType as the default Hibernate type mapping for all attributes exposed as java.util.UUID. That is covered in the documentation @ http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch06.html#types-registry
The solution suggested by Oleg did not work perfectly for me (it failed if you tried to persist a null value). Here is a tweaked solution that also works for null values.
In my case i am using EclipseLink though so if you are using Hibernate you might not need this.
public class UuidConverter implements AttributeConverter<UUID, Object> {
@Override
public Object convertToDatabaseColumn(UUID uuid) {
PGobject object = new PGobject();
object.setType("uuid");
try {
if (uuid == null) {
object.setValue(null);
} else {
object.setValue(uuid.toString());
}
} catch (SQLException e) {
throw new IllegalArgumentException("Error when creating Postgres uuid", e);
}
return object;
}
@Override
public UUID convertToEntityAttribute(Object dbData) {
return (UUID) dbData;
}
}