davioooh
davioooh

Reputation: 24666

Unable to generate UUID id for my entities

I'm working on a web project using:

I'm new to Postgres DB and for my tables I decided to use (for the first time) UUID identifiers, but I'm having some troubles...

For ID field I used Postgres uuid type and I set as default value uuid_generate_v4(). All works correctly when I generate a new row directly by a PSQL insert, but I cannot create a new record by my application.

As an example, this is how I declared an entity in my application:

@Entity
@Table(name = "users")
public class User {

    @Id
    @Type(type = "pg-uuid")
    private UUID id;

    // other fields and methods...

}

For this declaration I'm using the Type Hibernate annotation.

Find operations work well, but when I try to make an insert I get this exception:

org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before calling save(): net.myapp.User;

Followiong this tutorial I tried to solve the issue. I changed my entity definition to:

@Entity
@Table(name = "users")
public class User {

    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)")
    @Id
    private UUID id;

    // other fields and methods...
}

But now I'm getting wrong ID values when I retrieve (existing) data from DB (still haven't tried insert...).

So what is the right way to define ID field in my case?


UPDATE

Using the second definition...

When I try to find by ID, I'm getting:

org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bytea Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.

When I try to create new record:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a];

Upvotes: 10

Views: 17521

Answers (3)

Vinit Solanki
Vinit Solanki

Reputation: 2023

I used this configuration and this is working for me and I am using

  • Spring Boot 1.5.2
  • Hibernate 5
  • PostgreSQL 9.6

Entity.java

@Id  
@Column(updatable = false, nullable = false, columnDefinition = "uuid DEFAULT uuid_generate_v4()")
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

before that I am suggesting you to load uuid-ossp it into your database to use it.

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

Upvotes: 9

user6048742
user6048742

Reputation:

I use the following configuration and it works. I am using Glassfish as application server.

@Id
@GenericGenerator(name = "uuid", strategy = "uuid2")
@GeneratedValue(generator = "uuid")
@Column(name = "key", unique = true, nullable = false)
@Type(type="pg-uuid")
private UUID key;

The table key has the Postgres uuid type:

CREATE TABLE billuser.billingresult (key uuid NOT NULL,   .... )...

Upvotes: 5

m c
m c

Reputation: 1104

Worked as a charm:

  • Create a custom configuration class

    package mypackage;
    
    public class PostgresUuidDialect extends PostgreSQL9Dialect {
    
    @Override
    public void contributeTypes(final TypeContributions typeContributions, final ServiceRegistry serviceRegistry) {
        super.contributeTypes(typeContributions, serviceRegistry);
        typeContributions.contributeType(new InternalPostgresUUIDType());
    }
    
    protected static class InternalPostgresUUIDType extends PostgresUUIDType {
    
            @Override
            protected boolean registerUnderJavaType() {
                return true;
            }
        }
    }
    
  • In your application.properties add this

spring.jpa.database-platform=mypackage.PostgresUuidDialect

(change mypackage according to your needs)

Pros: you don't need to use any special annotation in your JPA entity

Cons: this obscure class in your project...

Upvotes: 0

Related Questions