我在数据库中有一个两列的主键,我需要使用hibernate 4.2和jpa使用spring mvc应用程序进行建模。从我在网上阅读的内容来看,我的复合键类ConceptPK似乎必须包含一个hashcode方法。问题在于主键的两个元素之一是BigInteger数据类型,但是hashcode()方法的默认返回类型是int。这导致eclipse在下面给出一条错误消息,表明该程序将无法编译,因为我的hashcode方法的返回类型错误。

我需要hashcode方法吗?为了使它可以使用功能正常的复合键ConceptPK进行编译,我必须对下面的代码做什么?

import java.io.Serializable;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import org.hibernate.annotations.Type;
import org.joda.time.DateTime;

@Embeddable
class ConceptPK implements Serializable {

@Column(name="id", nullable=false)
protected BigInteger id;

@Column(name="effectiveTime", nullable=false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime effectiveTime;

public ConceptPK() {}
public ConceptPK(BigInteger bint, DateTime dt) {
    this.id = bint;
    this.effectiveTime = dt;
}

/** getters and setters **/
public DateTime getEffectiveTime(){return effectiveTime;}
public void setEffectiveTime(DateTime ad){effectiveTime=ad;}

public void setId(BigInteger id) {this.id = id;}
public BigInteger getId() {return id;}

public boolean equals(Object o) {
    return ((o instanceof ConceptPK) &&
            effectiveTime.equals(((ConceptPK)o).getEffectiveTime()) &&
            id == ((ConceptPK) o).getId());
}

public int hashCode() {
    BigInteger sum = BigInteger.valueOf(
            effectiveTime.hashCode()
            );
    sum.add(id);
    return sum;//this line has error message indicating wrong return data type
}
}


这是使用ConceptPK作为其主键的类的代码:

@Entity
@Table(name = "tablename")
public class Concept implements Serializable{

    @EmbeddedId
    @AttributeOverrides({
        @AttributeOverride(name="id", column=@Column(name="id")),
        @AttributeOverride(name="effectiveTime", column=@Column(name="effectiveTime"))
    })
    private ConceptPK conceptPK;

    //lots of other stuff
}

最佳答案

覆盖超级方法时,请始终使用@Override
  类,如果您这样做,则编译器会在您执行某些错误操作时通知您
  实施。


错误消息错误的返回数据类型,编译器认为是正确的,您的sumBigInteger类型,而不是Integer


Integer是原始类型int的包装。因此,JVM将执行装箱和拆箱。
BigInteger是引用类型,JVM不会在此处执行装箱和拆箱。


解:

@Override
public int hashCode() {
    int hash = 3;
    hash = 53 * hash
            + ((effectiveTime == null) ? 0 : effectiveTime.hashCode());
    hash = 53 * hash + ((id == null) ? 0 : id.hashCode());
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    final ConceptPK other = (ConceptPK) obj;
    if (effectiveTime == null) {
        if (other.effectiveTime != null)
            return false;
    } else if (!effectiveTime.equals(other.effectiveTime))
        return false;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}

10-07 19:42
查看更多