首页 > 解决方案 > JPA 列不存在

问题描述

我有一个实体B,其中包含一个实体映射,<VC, P>其中的某些字段P,例如A,没有与我的连接表链接并给出错误:

PSQLException:错误:列pricing1_.pricing_a 不存在

我试图做到这一点,当我坚持我的主要实体时,B我的地图中的所有实体也将一次性地坚持下去(如果可能的话)。

当我这样做时都会发生此错误

bRepo.save(b);

pRepo.saveAll(b.getPricing().values()); // by here the values at least exists in its own table (p)
bRepo.save(b);

这就是我所拥有的

主体B

@Setter
@Getter
@Entity
@Table(name = "b")
public class B implements Serializable {

  @Id
  @Column(nullable = false)
  private String name;

  @OneToMany(cascade = CascadeType.ALL)
  @JoinTable(
          name = "b_p",
          joinColumns = @JoinColumn(name = "b_name", referencedColumnName = "name"))
  @MapKeyJoinColumns({
          @MapKeyJoinColumn(name = "p_c"),
          @MapKeyJoinColumn(name = "c_id")
  })
  private Map<VC, P> pricing = new LinkedHashMap<>();

  ...
}

地图pricing

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "v_c")
public class VC implements Serializable {

  @EmbeddedId private VCId vcId;
}

及其 (VC) 组合键

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class VCId implements Serializable {

  @Enumerated(EnumType.STRING)
  @Column(name = "p_c")
  private PC pC;

  @Column(name = "c_id")
  private String cId;
}

定价地图的价值

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
@Entity
@Table(name = "p")
public class P implements Serializable {

  @EmbeddedId private PId pId;
}

及其 (P) 键

@Setter
@Getter
@NoArgsConstructor
@Embeddable
public class PId implements Serializable {

  @Column(name = "a")
  private BigDecimal a; // complains about this field

  @Column(name = "d_a")
  private BigDecimal dA; // and will probably complain about this one too
}

我的桌子

CREATE TABLE b
(
    name   VARCHAR(100) NOT NULL PRIMARY KEY,
    ...
);

CREATE TABLE v_c
(
    p_c   TEXT         NOT NULL,
    c_id  VARCHAR(50)  NOT NULL,

    PRIMARY KEY (p_c, c_id)
);

CREATE TABLE p
(
    a       NUMERIC      NOT NULL,
    d_a     NUMERIC      NOT NULL DEFAULT 0.0,

    PRIMARY KEY (a, d_a)
);

CREATE TABLE b_p
(
    b_name     VARCHAR(100) NOT NULL,
    p_c        TEXT         NOT NULL,
    c_id       VARCHAR(50)  NOT NULL,
    a          NUMERIC      NOT NULL,
    d_a        NUMERIC      NOT NULL DEFAULT 0.0,

    PRIMARY KEY (b_name, p_c, c_id),
    
    FOREIGN KEY (b_name) REFERENCES b (name) ON DELETE CASCADE,
    FOREIGN KEY (p_c, c_id) REFERENCES v_c (p_c, c_id) ON DELETE CASCADE,
    FOREIGN KEY (a, d_a) REFERENCES p (a, d_a) ON DELETE CASCADE
);

我究竟做错了什么?

标签: javapostgresqljpaspring-data-jpa

解决方案


最后,我进行了以下更改并且效果很好:

将复合 ID 替换为自动增量 ID,并在我的表中添加了另一个新的自动p增量字段:v_cpricing_p_idb_p

CREATE TABLE v_c
(
    vc_id               BIGSERIAL    NOT NULL PRIMARY KEY,
    p_c   TEXT          NOT NULL,
    coin_id             VARCHAR(50)  NOT NULL
);

CREATE TABLE p
(
    p_id                BIGSERIAL    NOT NULL PRIMARY KEY,
    a                   NUMERIC      NOT NULL,
    d_a                 NUMERIC      NOT NULL DEFAULT 0.0,
    vc_id               BIGSERIAL,

    FOREIGN KEY (vc_id) REFERENCES v_c(vc_id) ON DELETE CASCADE
);

CREATE TABLE b_p
(
    b_name              VARCHAR(100)    NOT NULL,
    vc_id               BIGSERIAL       NOT NULL,
    pricing_p_id        BIGSERIAL       NOT NULL,

    PRIMARY KEY (b_name, vc_id, pricing_p_id),

    FOREIGN KEY (b_name) REFERENCES b (name) ON DELETE CASCADE,
    FOREIGN KEY (vc_id) REFERENCES v_c (vc_id) ON DELETE CASCADE,
    FOREIGN KEY (pricing_p_id) REFERENCES p (p_id) ON DELETE CASCADE
);

然后将定价字段的映射更新为如下所示:

  @OneToMany(cascade = CascadeType.ALL)
  @MapKeyJoinColumn(name = "vc_id") // this
  private Map<VC, P> pricing = new LinkedHashMap<>();

推荐阅读