在另一个复合键中使用复合键(@MapsId(“id_1,id_2,id_3”))?

时间:2017-08-06 11:15:48

标签: hibernate jpa java-ee

我在 class_a 中有 composite_id_a(id_1,id_2,id_3),并希望在 class_b composite_id_a >作为自己的 composite_id_b 的一部分。

class_b composite_id_a 作为其主键的一部分,也是其外键。

我应该如何在class_b中映射外键?

class_b:

public class B{

@EmbeddedId
private CompositeId_B composite_id_b;

// This does not work: I cannot use more properties in @MapsId
@MapsId("id_1, id_2, id_3")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumns({
        @JoinColumn(name="ID_1", referencedColumnName="ID_1"),
        @JoinColumn(name="ID_2", referencedColumnName="ID_2"),
        @JoinColumn(name="ID_3", referencedColumnName="ID_3")})
private A class_a;
}

B类的复合ID:

@Embeddable
public class Id_B{

@Column(name = "ID_1")
private Integer id_1;

@Column(name = "ID_2")
private Integer id_2;

@Column(name = "ID_3")
private Integer id_3;

@Column(name = "NAME")
private String name;
}

A类的复合ID:

@Embeddable
public class Id_A{

@Column(name = "ID_1")
private Integer id_1;

@Column(name = "ID_2")
private Integer id_2;

@Column(name = "ID_3")
private Integer id_3;
}

class_a:

public class A{

@EmbeddedId
private ID_A id_a;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumns({
        @JoinColumn(name="ID_1", referencedColumnName="ID_1"),
        @JoinColumn(name="ID_2", referencedColumnName="ID_2"),
        @JoinColumn(name="ID_3", referencedColumnName="ID_3")})
private Set<B> b = new HashSet<>();
}

我不能使用这样的内容,因为会抛出以下错误:

public class B{

@EmbeddedId
private CompositeId_B composite_id_b;

// This does not work: I cannot use more properties in @MapsId
@MapsId("composite_id_a")
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumns({
        @JoinColumn(name="ID_1", referencedColumnName="ID_1"),
        @JoinColumn(name="ID_2", referencedColumnName="ID_2"),
        @JoinColumn(name="ID_3", referencedColumnName="ID_3")})
private A class_a;
}

B类复合ID的另一个版本(不起作用):

@Embeddable
public class Id_B{

@EmbeddedId
private CompositeId_A composite_id_a;

@Column(name = "NAME")
private String name;
}


13:55:46,010 ERROR [org.hibernate.annotations.common.AssertionFailure:42] HCANN000002: An assertion failure occurred (this may indicate a bug in Hibernate): org.hibernate.annotations.common.AssertionFailure: Declaring class is not found in the inheritance state hierarchy: entity.CompositeId_B
    at org.hibernate.cfg.BinderHelper.getMappedSuperclassOrNull(BinderHelper.java:811)

1 个答案:

答案 0 :(得分:1)

这是JPA规范称之为“派生身份”的内容。在您提供的代码的mishmash :)上进行推测,您应该稍微区别地定义您的类:

@Embeddable
public class Id_A implements Serializable {
    @Column(name = "ID_1")
    private Integer id_1;

    @Column(name = "ID_2")
    private Integer id_2;

    @Column(name = "ID_3")
    private Integer id_3;
}

@Entity
@Table(name = "A")
public class A {
    @EmbeddedId
    private Id_A id;

    @OneToMany(mappedBy = "a", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<B> bSet = new HashSet<>();
}

@Embeddable
public class Id_B implements Serializable {
    Id_A aId;   // corresponds to PK type of A

    String name;
}

@Entity
public class B {
    @EmbeddedId
    private Id_B id;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumns({
        @JoinColumn(name="ID_1", referencedColumnName="ID_1"),
        @JoinColumn(name="ID_2", referencedColumnName="ID_2"),
        @JoinColumn(name="ID_3", referencedColumnName="ID_3")})
    @MapsId("aId")
    private A a;
}

请注意@MapsId上的B.a注释和OneToMany.mappedBy上的A.bSet设置。

另外,我相信你记录的一个Hibernate错误(“在继承状态层次结构中找不到声明类”)是在@EmbeddedId内有@Embeddable注释的结果。

在第2.4.1节的JPA 2.1规范中讨论了衍生身份(带有示例)。