java 如何在spring jpa中使用postgresql默认值?

3bygqnnd  于 2023-11-15  发布在  Java
关注(0)|答案(2)|浏览(186)

我有一个非常简单的问题,我有一个实体(我故意把它删掉了),它有id、name和另一个标识符(publicId),标识符的形式是uuid,但它是以字符串的形式存储在数据库中的。

@Entity
@Table(name = "some_entity")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SomeEntity extends BaseEntity<Long> {
    @Id
    @Column(name = "id", updatable = false, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "public_id", nullable = false)
    private String publicId;

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

字符串
对于这个实体,我有一个liquibase的sql格式迁移。它看起来像下面这样。

CREATE TABLE some_entity
(
    id          BIGINT GENERATED ALWAYS AS IDENTITY
        CONSTRAINT expense_card_pk PRIMARY KEY,
    public_id   VARCHAR(50)              NOT NULL DEFAULT uuid_generate_v4(),
    name        VARCHAR(50)              NOT NULL
);


如您所见,对于public_id字段,我使用了“uuid-ossp”包中的默认函数- uuid_generate_v4()。
现在,我试图保存我用lombok builder创建的SomeEntity对象。在builder中,我只指定了name字段。在spring repository的帮助下,我正在保存对象。但是!保存项目时出错。

ERROR: null value in column "public_id" of relation "expense_card" violates not-null constraint


我明白为什么会这样。Builder创建了一个对象,除了name之外,所有字段都为null。我试图保存这样一个对象,结果发现我在not null字段中保存了null。但这不是废话吗?postgres不应该处理这个吗?
无论如何,你能告诉我如何以uuid格式自动为public_id字段创建一个标识符,而不是在每次创建对象时都在构建器中进行?
理想情况下,我希望这个责任在数据库上。作为最后的手段,也许有一些jpa注解?
是的,顺便说一下,我想把这个标识符存储成字符串格式。

gijlo24d

gijlo24d1#

您可能希望检查uuid_generate_v4()-可以使用uuid_generate_v4()函数作为列的默认值。

CREATE TABLE some_entity
(
    id          BIGINT GENERATED ALWAYS AS IDENTITY
        CONSTRAINT expense_card_pk PRIMARY KEY,
    public_id   VARCHAR(50) DEFAULT uuid_generate_v4()::VARCHAR(50) NOT NULL,
    name        VARCHAR(50) NOT NULL
);

字符串
这确保了uuid_generate_v4()在被分配给public_id列之前被转换为VARCHAR(50);这样,当创建一个新的SomeEntity对象时,你不需要在你的构建器中指定publicId字段。
而且,不要忘记注解它!

@Column(name = "public_id", nullable = false, columnDefinition = "VARCHAR(50) DEFAULT uuid_generate_v4()::VARCHAR(50)")
private String publicId;

cx6n0qe3

cx6n0qe32#

由于您使用的是迁移工具,请使用@DynamicInsert注解您的实体类,并在public_id实体定义中删除nullable=false(在POJO中)。您必须强制Hibernate在创建insert语句时省略值public_id。然后DB将注意创建默认值。否则,由于您显式告诉DB在非空字段中保存null,您将违反约束
DynamicInsert会导致insert语句忽略在transaction中未赋值/更改的字段

相关问题