Persisting UUID in PostgreSQL using JPA

前端 未结 7 616
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-01 06:43

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\")
         


        
相关标签:
7条回答
  • 2020-12-01 06:55

    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:

    1. Whether to use ID, UUID or both. There is quick discussion over this.
    2. Using 'uuid' for names rather than 'id', it is misleading.
    3. Removing '-' signs from UUID, save 4 bytes.
    4. Generating UUID in @PrePersist section if you use Spring.
    0 讨论(0)
  • 2020-12-01 06:56

    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;
    }
    
    0 讨论(0)
  • 2020-12-01 07:00

    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").

    0 讨论(0)
  • 2020-12-01 07:00

    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.
    
    0 讨论(0)
  • 2020-12-01 07:06

    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

    0 讨论(0)
  • 2020-12-01 07:07

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题