【问题标题】:How can I use an UUID as an @Id for my @Entity properly?如何正确使用 UUID 作为 @Entity 的 @Id?
【发布时间】:2020-11-13 06:54:42
【问题描述】:

我想将 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

【问题讨论】:

    标签: java mysql spring-boot hibernate jpa


    【解决方案1】:

    首先我要notice那个:

    根据 JPA,只有以下类型应用作标识符属性类型:

    • 任何 Java 基本类型
    • 任何原始包装类型
    • java.lang.String
    • java.util.Date (TemporalType#DATE)
    • java.sql.Date
    • java.math.BigDecimal
    • java.math.BigInteger

    用于标识符属性的任何类型超出此列表将不可移植

    但是,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;
    

    【讨论】:

      猜你喜欢
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 2018-06-06
      • 1970-01-01
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      相关资源
      最近更新 更多