无法在 Hibernate/JPA/Spring 引导项目中创建包含 3 个字段的复合 PK

Unable to create a composite PK with 3 fields in Hibernate/JPA/Spring boot project

目标是建立一个连接 table (FormComponent),它将表单(通过 formId)绑定到组件 (componentId),并带有额外的 sortOrder 列。所有三列一起形成一个唯一的复合主键。

如果我只在我的@Embeddable class 中定义 formId 和 componentId,我的实现确实有效,但这不允许我有重复项(一个表单可能多次具有相同的组件)。

如果我将 sortOrder-column 添加到 PK 并加入 table class,我会收到以下错误:

    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132
    Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1786
        Caused by: javax.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
            Caused by: org.hibernate.MappingException at PersistentClass.java:862

复合PKclass:

@EqualsAndHashCode
@AllArgsConstructor
@Getter
@Embeddable
public class FormComponentId implements Serializable {
    @Column(name = "form_id")
    private Long formId;
    @Column(name = "component_id")
    private Long componentId;
    @Column(name = "sort_order")
    private Long sortOrder;
}

加入tableclass:

@Data
@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "form_component")
public class FormComponent {
    @EmbeddedId
    private FormComponentId id;
    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("formId")
    private Form            form;
    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("componentId")
    private Component       component;
    private Long            sortOrder;
}

如果我对文档的理解正确,我应该能够定义超过 2 列的复合 PK。

项目使用Springboot 2.5.1.

为了回答我自己的问题(睡个好觉之后),问题是在 FormComponent class 中定义了 sortOrder 列。

这样 form_component 就可以正确创建了:

@Data
@Getter
@Setter
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "form_component")
public class FormComponent {
    @EmbeddedId
    private FormComponentId id;
    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("formId")
    private Form            form;
    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("componentId")
    private Component       component;
}

form_component table 转储(来自 MariaDB):

CREATE TABLE form_component (
  sort_order bigint(20) NOT NULL,
  component_id bigint(20) NOT NULL,
  form_id bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE form_component
  ADD PRIMARY KEY (component_id,form_id,sort_order),
  ADD KEY FK1d1gjrgj8elln6irre9vj45e (form_id);

ALTER TABLE form_component
  ADD CONSTRAINT FK1d1gjrgj8elln6irre9vj45e FOREIGN KEY (form_id) REFERENCES form (id),
  ADD CONSTRAINT FKlbpvqdblh0i147fqctd7dhs6a FOREIGN KEY (component_id) REFERENCES component (id);