【问题标题】:Unable to generate UUID id for my entities无法为我的实体生成 UUID id
【发布时间】:2016-07-31 10:16:06
【问题描述】:

我正在做一个网络项目,使用:

  • Spring 4.x (Spring Boot 1.3.3)
  • 休眠 4.x
  • PostgreSQL 9.x

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

对于 ID 字段,我使用 Postgres uuid 类型并设置为默认值 uuid_generate_v4()。当我通过 PSQL 插入直接生成新行时,一切正常,但我的应用程序无法创建新记录。

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

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

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

    // other fields and methods...

}

对于这个声明,我使用Type Hibernate 注释。

Find 操作运行良好,但是当我尝试进行 insert 时,我得到了这个异常:

org.springframework.orm.jpa.JpaSystemException: 这个类的 ids 必须在调用 save() 之前手动分配:net.myapp.User;

关注this tutorial 我试图解决这个问题。我将实体定义更改为:

@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:错误:运算符不存在:uuid = bytea 提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。

当我尝试创建新记录时:

org.springframework.dao.InvalidDataAccessResourceUsageException:无法执行语句; SQL [不适用];

【问题讨论】:

  • 您是否尝试仅添加 @Id @GeneratedValue 而没有 ColumnGenericGenerator
  • @AliDehghani 谢谢我试试
  • 是的,通过 ORM 在 postgres 中使用 uuid 总是让人头疼。两年前我在这个问题上花了几天时间。一些提示: 1. 你需要在 postgresql 中启用 uuid(只要确保你可以从控制台生成它们) 2. uuid - bytea 错误意味着你的插入不正确,它将 id 保存为字节 3. 排除生成器问题首先尝试创建它们在 java 中:id = UUID.randomUUID();

标签: java spring hibernate postgresql jpa


【解决方案1】:

我使用了这个配置,这对我有用 我正在使用

  • Spring Boot 1.5.2
  • 休眠 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;

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

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

【讨论】:

    【解决方案2】:

    我使用以下配置并且它有效。我使用 Glassfish 作为应用服务器。

    @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 类型:

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

    【讨论】:

      【解决方案3】:

      作为一个魅力工作:

      • 创建自定义配置类

        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 实体中使用任何特殊注释

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

      【讨论】:

        猜你喜欢
        • 2020-10-26
        • 2021-10-11
        • 1970-01-01
        • 2013-05-10
        • 2018-01-14
        • 2017-08-24
        • 2017-06-20
        • 1970-01-01
        • 2016-04-14
        相关资源
        最近更新 更多