繁体   English   中英

如何重写哈希码和等于休眠中的瞬时对象?

[英]How to override hashcode and equals for transient object in hibernate?

我有3个实体,即学生,年级和班级。 代码如下所示。 这只是一个示例。

学生班

public class Student implements Serializable{
    private static final long serialVersionUID = 1L;
    private String fullName;
    private long studentId;

    //omit getter/setter column mapped to db

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getFullName() == null) ? 0 : getFullName().hashCode());
        result = prime * result + (int) (getStudentId() ^ (getStudentId() >>> 32));
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof Student)
            return false;
        test other = (test) obj;
        if (getFullName() == null) {
            if (other.getFullName() != null)
                return false;
        } else if (!getFullName().equals(other.getFullName()))
            return false;
        if (getStudentId() != other.getStudentId())
            return false;
        return true;
    }
}

SchoolClass班:

public class SchoolClass implements Serializable{
    private static final long serialVersionUID = 1L;
    private String className;
    private long classId;

    //omit getter/setter column mapped to db

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (getClassId() ^ (getClassId() >>> 32));
        result = prime * result + ((getClassName() == null) ? 0 : getClassName().hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof SchoolClass)
            return false;
        SchoolClass other = (SchoolClass) obj;
        if (getClassId() != other.getClassId())
            return false;
        if (getClassName() == null) {
            if (other.getClassName() != null)
                return false;
        } else if (!getClassName().equals(other.getClassName()))
            return false;
        return true;
    }

}

年级:

public class Grade implements Serializable{
    private static final long serialVersionUID = 1L;
    private SchoolClass  schoolClass;
    private Student student;

    //omit getter/setter column mapped to db

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getSchoolClass() == null) ? 0 : getSchoolClass().hashCode());
        result = prime * result + ((getStudent() == null) ? 0 : getStudent().hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (obj instanceof Grade)
            return false;
        Grade other = (Grade) obj;
        if (getSchoolClass() == null) {
            if (other.getSchoolClass() != null)
                return false;
        } else if (!getSchoolClass().equals(other.getSchoolClass()))
            return false;
        if (getStudent() == null) {
            if (other.getStudent() != null)
                return false;
        } else if (!getStudent().equals(other.getStudent()))
            return false;
        return true;
    }
}

因此,我在hibernate doc上检查了哈希码并等于它,它对于存在于数据库中的实体非常有效。 我的问题是保存到数据库之前需要新的临时实体对象。 我专门使用HashSet对Student和SchoolClass进行了单独的测试,如果setset尝试添加相同的对象,则其大小不会增加。

Student s1 = studentRepo.findById(studentId).get();
SchoolClass sc = scRepo.findById(classId).get();
Grade grade = new Grade();
grade.setStudent(s1);
grade.setSchoolClass(sc);
grades.add(grade);
logger.info(grades.size());

在这里,我有一个新的成绩集,并准备好这个成绩集并保存到db中。 问题来了,这个集合将包含重复的成绩对象。 这意味着将有2个条目具有相同的学生和相同的班级。 在年级课程中,我覆盖了其哈希码并等于Student和SchoolClass,它不应有重复的条目。 我认为这可能是因为新的Grade对象处于过渡状态? 不太清楚是什么原因。

当然,我可以通过手动方式对成绩进行唯一检查,但是哈希码和等号应该是正确的方法,不是吗?

那么如何解决呢? 需要一些帮助。

感谢@samabcde。 他是对的,我想念! 在条件检查上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM