关于Java:无法为我的实体生成UUID ID

Unable to generate UUID id for my entities

我正在使用以下项目处理Web项目:

  • Spring 4.x(Spring Boot 1.3.3)
  • hibernate4.x
  • PostgreSQL 9.x

我是Postgres DB的新手,我决定对表使用(首次)UUID标识符,但是我遇到了一些麻烦...

对于ID字段,我使用Postgres UUID类型,并将其设置为默认值uuid_generate_v4()。当我直接通过PSQL插入生成新行时,所有文件都可以正常工作,但是我无法通过应用程序创建新记录。

例如,这是我在应用程序中声明实体的方式:

1
2
3
4
5
6
7
8
9
10
11
@Entity
@Table(name ="users")
public class User {

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

    // other fields and methods...

}

对于此声明,我使用的是Type Hibernate批注。

查找操作效果很好,但是当我尝试进行插入操作时,出现此异常:

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

按照本教程的操作,我试图解决该问题。我将实体定义更改为:

1
2
3
4
5
6
7
8
9
10
11
12
@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...
}

但是现在当我从数据库检索(现有)数据时,我得到了错误的ID值(仍然没有尝试插入...)。

那么在我的情况下定义ID字段的正确方法是什么?

更新

使用第二个定义...

当我尝试通过ID查找时,我得到了:

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.

当我尝试创建新记录时:

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


我使用了此配置,这对我和
我正在使用

  • Spring启动1.5.2
  • hibernate5
  • PostgreSQL 9.6

Entity.java

1
2
3
4
5
@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;

在此之前,我建议您将uuid-ossp加载到数据库中以使用它。

1
CREATE EXTENSION IF NOT EXISTS"uuid-ossp";

我使用以下配置,并且可以正常工作。我正在使用Glassfish作为应用程序服务器。

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

表键具有Postgres uuid类型:

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

作为护身符:

  • 创建自定义配置类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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;
            }
        }
    }
  • 在您的application.properties中添加此

spring.jpa.database-platform = mypackage.PostgresUuidDialect

(根据您的需要更改mypackage)

优点:您无需在JPA实体中使用任何特殊的注释

缺点:项目中这个晦涩的类...