首页 > 解决方案 > JPA使复合外键的一部分成为主键的一部分

问题描述

我正在查看所有可能的 Google 搜索和 Stackoverflow 搜索,但找不到我要查找的内容。我的问题是有一个 A 类和一个 B 类,A 类有一个复合主键,B 类有一个原始主键。这些类(表)与一个名为 C 的类连接,我需要这个,因为连接中还有其他数据(底部的示例)。在 CI 类中显然有 B 类和 A 类的主键作为外键,但是我需要 B 类的复合键和 A 的外键的第一个属性作为 C 类的主键。

仅用文字有点难以理解,所以这里是示例:

public class CompositeId implements Serializable {
    private Long id;

    private Long version;

    // Other stuff...
}

@Entity
@IdClass(CompositeId.class)
public class A {
    @Id
    private Long id;

    @Id
    private Long version;

    private String name;

    private String creatorName;

    // Other stuff...
}

@Entity
public class B {
    private Long id;

    private String name;

    // Othet stuff...
}

public class CompositeJoinId implements Serializable {
    private Long aId; // Should equal to aReference's id property.

    private Long bId; // Should equal to bReference's id property.

    // Other stuff...
}

@IdClass(CompositeJoinId.class)
@Entity
public class C {
    @Id
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="a_id", referencedColumnName="id"),
        @JoinColumn(name="a_version", referencedColumnName="version")
    })
    private A aReference;

    @Id
    @ManyToOne
    @JoinColumn(name = "b_id")
    private B bReference;

    private Long day;

    // Other stuff...
}

有没有办法做到这一点?我所有的发现只使用一个使用两个外键的类,但我只需要/想要一个。

标签: mysqlhibernatejpa

解决方案


我不完全确定我理解你的问题;但我会像这样映射你的类(主要区别是CompositeJoinId):

public class CompositeId implements Serializable {
    private Long id;

    private Long version;

    // Other stuff...
}

@Entity
@IdClass(CompositeId.class)
public class A {
    @Id
    private Long id;

    @Id
    private Long version;

    private String name;

    private String creatorName;

    // Other stuff...
}

@Entity
public class B {
    @Id
    private Long id;

    private String name;

    // Othet stuff...
}

public class CompositeJoinId implements Serializable {
    private Long aId;

    private Long bReference; // matches name of @Id attribute and type of B PK

    // Other stuff...
}

@IdClass(CompositeJoinId.class)
@Entity
public class C {
    @Id
    @Column(name = "a_id", insertable = false, updatable = false)
    Long aId;

    @Id
    @ManyToOne
    @JoinColumn(name = "b_id")
    private B bReference;

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name="a_id", referencedColumnName="id"),
        @JoinColumn(name="a_version", referencedColumnName="version")
    })
    private A aReference;

    private Long day;

    // Other stuff...
}

这些是派生身份的示例;JPA 2.2 规范中的第 2.4.1 节讨论了派生身份和派生身份。


推荐阅读