【问题标题】:Spring data JPA generated uuid field is nullSpring data JPA 生成的 uuid 字段为空
【发布时间】:2017-11-28 16:52:55
【问题描述】:

我有一个名为 Booking 的实体,它有一个生成的 id 字段,我将其用作主键。它工作正常。我想添加另一个字段 uuid,我将在 REST API 中将其用作资源标识符。 我有一个 Postgres 数据库,并将该字段设置为自动生成:

uuid character varying(36) not null default uuid_generate_v1mc()

在创建时,数据库生成 id 和 uuid 就好了,但在 Java 代码中,uuid 字段为空。我的实体如下所示:

@Entity
public class Booking {

    @Id
    @SequenceGenerator(name="booking_id_seq", sequenceName="booking_id_seq", allocationSize=1)
    @GeneratedValue(strategy= GenerationType.IDENTITY, generator = "booking_id_seq")
    private Long id;

    @Column(nullable = false)
    private String uuid;
(...)
}

我做错了什么?

跟进: 谢谢大家的cmets和答案。看起来我有两个选择,要么从数据库重新加载实体以让数据库生成 uuid,要么自己在代码中生成它。哪个是首选?我猜后者的性能更高,但还有什么需要考虑的吗?

【问题讨论】:

  • 只有@Id 字段会自动与数据库同步,其他生成的字段不会。您将不得不从数据库中重新加载实体。
  • 只生成id。 uuid 不是 id,因此不会自动生成,您必须设置一个值,因为该字段不可为空。

标签: java spring postgresql hibernate jpa


【解决方案1】:

您可以在实体类中使用@PrePersist 进行填充

@PrePersist
public void autofill() {
    this.setUuid(UUID.randomUUID().toString());
}

我为您的问题创建了一个示例项目 https://github.com/zz-chen/Sample-spring-data-jpa-generate-uuid

你可以用命令运行它

gradle bootRun

你会收到这样的消息

2017-06-26 11:12:16.118 信息 78681 --- [主要] hello.Application : 客户发现 findOne(1L):2017-06-26 11:12:16.119 信息 78681 --- [主要] 你好。应用程序: -------------------------------- 2017-06-26 11:12:16.120 INFO 78681 --- [主要] hello.Application : Customer[id=1, firstName='Jack', 姓氏='鲍尔',uuid='44969325-c31f-4b8e-96d6-a59ff9b845b6'] 2017-06-26 11:12:16.122 信息 78681 --- [主要] 你好。申请时间:2017-06-26 11:12:16.122 信息 78681 --- [主] hello.Application
:使用 findByLastName('Bauer') 找到客户:2017-06-26 11:12:16.122 信息 78681 --- [主] hello.Application
: -------------------------------------------------------- 2017-06-26 11:12:16.158 信息 78681 --- [主] hello.Application
: 客户[id=1, firstName='Jack', 姓氏='鲍尔',uuid='44969325-c31f-4b8e-96d6-a59ff9b845b6'] 2017-06-26 11:12:16.158 信息 78681 --- [主要] 你好。应用程序:客户[id = 3, 名字='金', lastName='Bauer',uuid='0cef24ad-ce97-4c79-b8a4-69ff575326fb']

通过该消息,我们可以确认 uuid 字段工作正常!!!

【讨论】:

  • 谢谢,我最终使用了您的解决方案,因为我认为使用 PrePersist 更优雅。
【解决方案2】:

您只需在实体中的字段上添加以下内容:

import java.util.UUID;

@Column(unique = true, name = "uuid", nullable = false)
private String uuid = UUID.randomUUID().toString().toUpperCase();

【讨论】:

  • 我认为这不是一个好的解决方案,如果我们从数据库中读取,当 JPA 读取每条记录并将其序列化为对象时,它所做的就是使用默认值创建一个对象空构造函数,然后uuid = UUID.randomUUID().toString().toUpperCase() 将被不必要地执行,虽然该值将被 JPA 序列化程序用数据库中的值覆盖,但第一个在处理器消耗方面并不便宜
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2018-11-11
  • 2019-02-20
  • 2013-10-12
  • 2018-05-14
  • 1970-01-01
相关资源
最近更新 更多