0

A级

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "A")
    private Set<B> Bs = new HashSet<B>();

B类

@ManyToOne(fetch = FetchType.EAGER)
    @JoinColumns({
            @JoinColumn(name = "INT_C", nullable = false, insertable = false, updatable = false),
            @JoinColumn(name = "SBC_C", nullable = false, insertable = false, updatable = false) })
    private A a;

当我这样做时,getB()我只会得到一行,而对于 and 的组合INT_CSBC_C则存在 3 行。

请让我知道这里有什么问题。

    Rows in DB

    SBC_C  INT_C FILE_C      OUTPUT_FILE_NM 
     --------------------------------------------
    MYACCESS  CR   CRC        DataHub_DEVC.dat  
    MYACCESS  CR   CRG        DataHub_DEVG.dat  
    MYACCESS  CR   CRU        DataHub_DEVU.dat

B 实体 ID:

@EmbeddedId
    private ObFileId id;

ObFileId 类:

@Embeddable
public class ObFileId implements IXDomain {

@Override
public int hashCode() {
    return getICode().hashCode() + getSCode().hashCode();
}

@Override
public boolean equals(Object obj) {
    return ((obj instanceof ObFileId)
            && (getICode().equals(((ObFileId) obj)
    .getICode())) && (getSubscriberCode()
    .equals(((ObFileId) obj).getSCode())));
}
4

1 回答 1

0

当您计划在 中添加对象时CollectionsSet您必须重写equals()andhashCode()方法,以便系统可以比较 2 个实例并检测它们是否相等。在Sets中,您不能有重复项,因此当您添加一个实例并且其中的另一个实例Set等于该实例时,第二个实例将不会添加到Set.

equals()一个带有intas的方法示例id,它可以完美地识别实例(主键):

@Override
public boolean equals(Object o) {
    if (o instanceof B) {
        B b = (B)o;
        return b.id == this.id;
    }
    return false;
}

还有一种可能的hashCode()方法:

@Override
public int hashCode() {
    return new Integer(id).hashCode();
}

尝试更多地了解这两种方法,因为它们在 Java 编程中非常重要,尤其是在 JPA/Hibernate 中。

编辑:

embeddable 类包括 2 个字段,但它不是 B 表的主键,因为 3 行对于这 2 个字段具有完全相同的值。这 3 行被认为是相等的,并且在第一次插入之后Set,其他 2 行不被添加。

将构成 B 表主键的所有字段添加到您的可嵌入类中,并修改您的equals()hashCode()方法以包含新字段(FILE_C字段可能是唯一的缺失字段)。然后行应该被认为是不同的,每一行都应该添加到Set.

于 2013-07-02T21:02:42.940 回答