我在数据库中有一个双列主键,我需要使用hibernate 4.2和jpa使用spring mvc应用程序进行建模。从我在线阅读的内容来看,我的复合密钥类ConceptPK
似乎必须包含一个哈希码方法。问题是主键的两个元素之一是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
}
答案 0 :(得分:3)
请记住,哈希码不需要是唯一的,它们只需要对包含相同字段值的2个类相同。
那么为什么不将每个字段的hashCode一起添加到一起?:
public int hashCode() {
return id.hashCode() + effectiveTime.hashCode();
}
当然,这并不能处理空字段,但我会把它留给你。 : - )
答案 1 :(得分:1)
每当覆盖超级方法时,始终使用
@Override
如果你这样做,编译器会在你做错的时候通知你 实施
错误消息错误的返回数据类型编译器说的是正确的,sum
的类型为BigInteger
而不是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;
}