【发布时间】:2021-12-12 23:03:39
【问题描述】:
我正在尝试使用 LinkedHashMap 为我的主要实体 B 创建一个 OneToMany 映射,其中包含实体 VC 和 P,但我收到以下错误:
集合映射中的重复列: com.test.model.B.pricing 列:b_name
我可能是错的,但我相信它与@JoinColumns 或@MapKeyJoinColumn 注释有关,因为我以前没有做过这样的事情,所以我很确定我做这部分不正确.
我的目标是我应该能够提供三个字段:
b_name pc 和 c_id 例如VC/VCId
为了得到a 和d_a 例如P.
另外,如果有更好的方法来构建事物,那么我会全神贯注,因为我个人不太喜欢我设置表格的方式(如果我能有 b 和b_p 表,其中b_p 可以只包含来自p 映射的所有五个字段(键和值)。
这是我的主要实体
@Setter
@Getter
@Entity
@Table(name = "b")
public class B implements Serializable {
@Id
@Column(nullable = false)
private String name;
@OneToMany(cascade = CascadeType.PERSIST)
@JoinTable(
name = "b_p",
joinColumns = @JoinColumn(name = "b_name", referencedColumnName = "name"))
@MapKeyJoinColumns({
@MapKeyJoinColumn(name = "b_name"),
@MapKeyJoinColumn(name = "p_c"),
@MapKeyJoinColumn(name = "c_id")
})
private Map<VC, Price> pricing = new LinkedHashMap<>();
...
}
地图的钥匙
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "v_c")
public class VC implements Serializable {
@EmbeddedId private VCId vcId;
}
密钥的 PK/复合密钥
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class VCId implements Serializable {
@Column(name = "b_name")
private String bName;
@Column(name = "p_c")
private SomeEnum pc;
@Column(name = "c_id")
private String cId;
}
地图的价值
@Setter
@Getter
@NoArgsConstructor
@Embeddable
@Entity
@Table(name = "price")
public class Price implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "amount")
private BigDecimal amount;
@Column(name = "discount_amount")
private BigDecimal discountAmount;
}
数据库表
CREATE TABLE b
(
name VARCHAR(100) NOT NULL PRIMARY KEY
...
);
CREATE TABLE v_c
(
bundle_name VARCHAR(100) NOT NULL,
physical_currency TEXT NOT NULL,
coin_id VARCHAR(50) NOT NULL,
FOREIGN KEY (b_name) REFERENCES b (name) ON DELETE CASCADE,
PRIMARY KEY (b_name, p_c, c_id)
);
CREATE TABLE p
(
id BIGSERIAL NOT NULL PRIMARY KEY,
amount NUMERIC,
discount_amount NUMERIC DEFAULT 0.00
);
CREATE TABLE b_p
(
bname VARCHAR(100) NOT NULL,
p_c TEXT NOT NULL,
c_id VARCHAR(50) NOT NULL,
price_id BIGSERIAL NOT NULL,
FOREIGN KEY (b_name, p_c, c_id) REFERENCES v_c (b_name, p_c, c_id) ON DELETE CASCADE,
FOREIGN KEY (price_id) REFERENCES price (id) ON DELETE CASCADE,
PRIMARY KEY (b_name, p_c, c_id)
);
【问题讨论】:
-
让 bundle_name 成为 VirtualCurrency 的一部分似乎违反直觉。您不希望您的虚拟货币可用于多个捆绑包吗?
-
@Lookslikeitsnot well 我拥有 bundle_name 的唯一原因只是因为我想确保获得特定捆绑包的正确 VirtualCurrency。从理论上讲,另一个捆绑包可以具有相同的 VirtualCurrency 是完全没问题的,并且 100% 可能,实际上这是预期的,但最终每个捆绑包的定价可能不同。如果我可以在不使用 bundle_name 作为复合键的一部分的情况下实现这一点,那么我 100% 会。
-
这不是通过在 b_p 中设置 b_name 和 b_name, p_c, c_id 作为该表的 PK 来实现的吗?将
FOREIGN KEY (b_name) REFERENCES b (name) ON DELETE CASCADE添加到 b_p,您可以从 v_c 中删除 b_name。 -
@Lookslikeitsnot Awesome,非常感谢,伙计!
标签: java spring postgresql jpa