当前位置: 首页 > 知识库问答 >
问题:

使用重叠的复合主键和外键Hibernate

孔梓
2023-03-14

我有一些实体:

@Entity
@Table(name = "cbonus")
public class BonusEntity {
    @EmbeddedId
    @AttributeOverride(name = "id", column = @Column(name = "id"))
    @AttributeOverride(name = "clusterId", column = @Column(name = "cluster_id"))
    private BonusId bonusId;
    private boolean released;
    
    @ManyToOne(targetEntity = AccountEntity.class, optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", insertable = false, updatable = false)
    @JoinColumn(name = "bank_id", referencedColumnName = "bank_id", insertable = false, updatable = false)
    @JoinColumn(name = "user_id", referencedColumnName = "user_id", insertable = false, updatable = false)
    private AccountEntity account;
}

@Entity
@Table(name = "account")
public class AccountEntity {

    @EmbeddedId
    @AttributeOverride(name = "clusterId", column = @Column(name = "cluster_id"))
    @AttributeOverride(name = "bankId", column = @Column(name = "bank_id"))
    @AttributeOverride(name = "userId", column = @Column(name = "user_id"))
    @NotNull
    private AccountId accountId;

    // other fields
}

当我试图保存新的cbonus记录时,出现异常:

org.postgresql.util.PSQLException: ERROR: null值在列"bank_id"的关系"cBonus"违反了非空约束详细信息:失败的行包含(773, gp3, null, null, f)。

和查询

DEBUG 24817-[nio-8080-exec-4]org . hibernate . SQL < br >:insert into CBO NUS(released,cluster_id,id)值(?, ?, ?)

在保存之前,对象已填充所有字段。我试图删除空值约束,但随后这些值只是保持为空值。我认为原因是复合主键和复合外键重叠。

我该如何使用Hibernate来管理它?

数据库模式:

CREATE TABLE cbonus
(
    id         BIGINT                NOT NULL,
    cluster_id TEXT                  NOT NULL,
    bank_id    BIGINT                NOT NULL,
    user_id    TEXT                  NOT NULL,
    released   BOOLEAN DEFAULT FALSE NOT NULL,
    FOREIGN KEY (cluster_id, bank_id, user_id) REFERENCES account,
    PRIMARY KEY (id, cluster_id)
);

CREATE TABLE account
(
    cluster_id TEXT       NOT NULL,
    bank_id    BIGINT     NOT NULL,
    user_id    TEXT       NOT NULL,
    -- [other fields]
    PRIMARY KEY (cluster_id, bank_id, user_id)
);

共有1个答案

仲孙钊
2023-03-14

您的映射是错误的。根据您的设置,bank_id列永远不会“可写”。你需要这个:

    @AttributeOverride(name = "id", column = @Column(name = "id"))
    @AttributeOverride(name = "clusterId", column = @Column(name = "pk_cluster_id"))
    private BonusId bonusId;

    @ManyToOne(targetEntity = AccountEntity.class, optional = false, fetch = FetchType.LAZY)
    @JoinColumnsOrFormulas({
       @JoinColumnOrFormula(column = @JoinColumn(name = "bank_id", referencedColumnName = "bank_id")),
       @JoinColumnOrFormula(column = @JoinColumn(name = "user_id", referencedColumnName = "user_id")),
       @JoinColumnOrFormula(formula = @JoinFormula(value = "cluster_id", referencedColumnName = "cluster_id"))
    private AccountEntity account;

    })

和一些模式修复:

CREATE TABLE command_response
(
    id                   BIGSERIAL PRIMARY KEY,
    pk_cluster_id        TEXT                    NOT NULL,
    cluster_id           TEXT                    NOT NULL,
    bank_id              BIGINT                  NOT NULL,
    ...
    FOREIGN KEY (cluster_id, bank_id, user_id) REFERENCES account,
    PRIMARY KEY (id, pk_cluster_id)
 类似资料:
  • 问题内容: 如何使用复合主键作为外键?看来我的尝试无效。 问题答案: 该行: 是错的。您不能那样使用,这只是父表中PK约束的名称。要将复合主键用作外键,您必须向子表中添加相同数量(组成PK)的相同数据类型的列,然后在定义中使用这些列的组合:

  • 如何将复合主键用作外键?看来我的尝试没有成功。

  • 我有两个表:A和B,都有一个复合主键。表B的PK也是表a主键的外键。 当我试图获取映射表B的类的实例时,我得到了以下异常: org.hibernate.TypeMismatchException 这两个类都位于package:com.cairone.ejemple01.entities 完整的日志输出为: 2016-09-21 12:28:24.505错误8568--[main] O.S.Boot

  • 我为这个特殊的问题找了很多,但我没有找到任何具体的解决办法。我在一个表中有一个复合主键,这个复合主键的一个字段是另一个表的复合主键的一部分。您可以说这个特定的字段是第二个表中的外键,但是在表定义中没有定义任何独占外键约束。对于第一个表中的每个rec,第二个表中可能有多条记录。我试图使用SPringBoot-JPA-Hibernate实现这一点,但无法实现。有人能帮我吗。以下是德泰:- 我有一个US

  • 问题内容: 我有一个类似的问题,如下所示,但解决方案无法解决我的问题。 休眠复合主键包含复合外键,如何映射 我正在尝试加入2个表,每个表都有一个带有部分外键引用的复合主键。 在一个: 在BPK中: 上面的方法给我这个异常: 你能帮忙吗? 问题答案: 假设f1和F2唯一标识A并存在于APK中,则可以通过几种方式使用JPA 2.0的派生ID。最容易显示的是: 这里的关键点是B对A的引用控制了外键字段f

  • 问题内容: 我有一个类似的问题,如下所示,但解决方案无法解决我的问题。 休眠复合主键包含复合外键,如何映射 我正在尝试加入2个表,每个表都有一个带有部分外键引用的复合主键。 在一个: 在BPK中: 上面的方法给我这个异常: 你能帮忙吗? 问题答案: 假设f1和F2唯一标识A并存在于APK中,则可以通过几种方式使用JPA 2.0的派生ID。最容易显示的是: 这里的关键点是B对A的引用控制了外键字段f