Liquibase 很好地创建了关系,但 Hibernate 在我与 Spring Boot 的集成测试中没有

Liquibase creates the relationships well but Hibernate doesn't in my integration tests with Spring Boot

我正在 运行在 Spring Boot 中安装一个嵌入式 postgres 数据库用于集成测试。

我们的想法是禁用 liquibase 进行集成测试,因为它会在我们的项目中填充大量不必要的测试数据。启用 liquibase 后测试有效,但我尝试了这种方法:

spring:
  liquibase:
    enabled: false
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true

Hibernate 会创建关系,但如果您在关系的一端留空,它们就会失败。

这是我得到的错误:

ERROR: insert or update on table "faq" violates foreign key constraint "fkponmkmbropnkmq3y1juw9v44"
  Detail: Key (id)=(1) is not present in table "faq_subcategory".

这是 Faq 实体中的关系:

    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @JoinColumn(name = "subcategory_id", nullable = true)
    @JsonIgnore
    private FAQSubcategory faqSubcategory;

这是 FaqSubcategory 实体中的关系:

    @OneToMany(mappedBy = "id", fetch = FetchType.LAZY, orphanRemoval = false)
    private List<Faq> faqs;

optional = truenullable = true 是多余的,但我把它放在那里以防万一,但仍然得到同样的错误。我不确定我错过了什么。

一个子类别可以有很多常见问题解答,每个常见问题解答可以属于一个子类别,但不需要。如果我 运行 一个 INSERT 语句直接在 postgres 数据库上使用 subcategory_id = null 它不会抱怨。

有什么想法吗?

谢谢。

编辑 1:

按照@Gleb Yan 的建议,我比较了两种模式。

当我用 liquibase 创建它时,DDL 是:

CREATE TABLE public.faq (
    id int8 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    creation_date timestamp(6) NULL,
    creator_id varchar(255) NULL,
    modification_date timestamp(6) NULL,
    modifier_id varchar(255) NULL,
    "name" varchar(255) NULL,
    order_int int4 NULL,
    active bool NULL,
    subcategory_id int8 NULL,
    CONSTRAINT faq_pkey PRIMARY KEY (id),
    CONSTRAINT fk_faq_faq__subcategory FOREIGN KEY (subcategory_id) REFERENCES public.faq_subcategory(id)
);

但是使用 hibernate.ddl-auto=create-drop 它会创建两个外键:

CREATE TABLE public.faq (
    id bigserial NOT NULL,
    creation_date timestamp NULL,
    creator_id varchar(255) NULL,
    modification_date timestamp NULL,
    modifier_id varchar(255) NULL,
    active bool NULL,
    "name" varchar(255) NULL,
    order_int int4 NULL,
    subcategory_id int8 NULL,
    CONSTRAINT faq_pkey null,
    CONSTRAINT fkoqpq35oftfpexvtkutja0p4ab FOREIGN KEY (subcategory_id) REFERENCES public.faq_subcategory(id),
    CONSTRAINT fkponmkmbropnkmq3y1juw9v44 FOREIGN KEY (id) REFERENCES public.faq_subcategory(id)
);

为什么休眠要这样做?

编辑 2:

我已经尝试将注释更改为:

    @ManyToOne(targetEntity = FAQSubcategory.class)
    @JsonIgnore
    private FAQSubcategory faqSubcategory;
    @OneToMany(targetEntity = FAQ.class, fetch = FetchType.LAZY)
    private List<FAQ> faqs;

现在 hibernate 仅使用 1 个外键即可正确执行 DDL,但如果我再次打开 liquibase,它就不起作用了。

Caused by: org.postgresql.util.PSQLException: ERROR: column "faq_subcategory_id" of relation "faq" does not exist

我无法理解它。

终于找到了。我用 faq 的 id 而不是 subcategoryId 字段映射了子类别。

上一个:

    @OneToMany(mappedBy = "id", fetch = FetchType.LAZY, orphanRemoval = false)
    private List<Faq> faqs;

工作之一:

    @OneToMany(mappedBy = "faqSubcategory", fetch = FetchType.LAZY)
    private List<FAQOKHelp> faqs;