java - 如何正确使用 UUID 作为我的 @Entity 的 @Id?

标签 java mysql spring-boot hibernate jpa

我想将 Spring Boot 中的用户实体存储到 MySQL 数据库中,并且我想使用 UUID 作为 Id。但是当我按照在线解决方案进行操作时,我只得到 The userId doesn't have a default value。我只是不知道出了什么问题。这是代码:

用户实体:

@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "user")
@Data
public class User {

    @JsonProperty("userId")
    @Column(name = "userId", columnDefinition = "BINARY(16)")
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    @Id
    private UUID userId;
    
    @JsonProperty("email")
    @Column(name = "email", nullable = false)
    private String email;
    
    @JsonProperty("name")
    @Column(name = "name", nullable = false)
    String name;

    @JsonProperty("surname")
    @Column(name = "surname", nullable = false)
    String surname;

    @JsonProperty("password")
    @Column(name = "password", nullable = false)
    private String password;
}

MySQL 表:

create table if not exists user (
   userId binary(16) not null primary key,
   name varchar(80) not null,
   surname varchar(80) not null,
   email varchar(120) not null,
   password varchar(120) not null
);

错误信息:

SQL Error: 1364, SQLState: HY000

2020-07-23 15:31:29.234 ERROR 16336 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : Field 'userId' doesn't have a default value
2020-07-23 15:31:29.251 ERROR 16336 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement] with root cause

最佳答案

首先我要notice那:

According to JPA only the following types should be used as identifier attribute types:

  • any Java primitive type
  • any primitive wrapper type
  • java.lang.String
  • java.util.Date (TemporalType#DATE)
  • java.sql.Date
  • java.math.BigDecimal
  • java.math.BigInteger

Any types used for identifier attributes beyond this list will not be portable.

但是, hibernate supports UUID 标识符值生成。这是通过其 org.hibernate.id.UUIDGenerator id 生成器支持的。

您可以使用默认策略,即根据 IETF RFC 4122 的第 4 版(随机)策略。

@Id
@Column(name = "userId", columnDefinition = "BINARY(16)")
@GeneratedValue
private UUID userId;

或者另一种策略,即 RFC 4122 版本 1(基于时间)策略(使用 IP 地址而不是 mac 地址)。

@Id
@Column(name = "userId", columnDefinition = "BINARY(16)")
@GeneratedValue(generator = "custom-uuid")
@GenericGenerator(
    name = "custom-uuid",
    strategy = "org.hibernate.id.UUIDGenerator",
    parameters = {
        @Parameter(
            name = "uuid_gen_strategy_class",
            value = "org.hibernate.id.uuid.CustomVersionOneStrategy"
        )
    }
)
private UUID userId;

关于java - 如何正确使用 UUID 作为我的 @Entity 的 @Id?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63056093/

相关文章:

java - 如何在泛型类中正确键入 no-arg 和 withVar 构造函数?

php - 如何避免查询加倍插入数据库?

mysql - 在大型 MySQL 表中添加新列

rest - Spring boot RestController 不能与实现接口(interface)的类一起使用

spring-boot - 在 spring boot 应用程序中使用关键的 cloud foundry redis 和 rabbitmq 服务作为 vcap 服务

java - 文件路径上带有空格的 JDBC 连接字符串(sqlite、hsqldb)

java - 为什么在 Struts 1.2.7 中延迟实例化 MessageResourcesFactory?

java - 聚合或组合

mysql - 按特定ID计算select语句值组的总和

java - 对行的某种类型实现分页