当前位置: 首页 > 知识库问答 >
问题:

Spring Data JPA save()方法不遵循hashCode/equals约定

太叔英卫
2023-03-14

我在下面的一个简单的Employee实体中实现hashcode/equals时遇到了问题。我想在其上实现相等的自定义域是“_id”字段。

当我保存两个具有相同值(即“111”)的employee对象时,我希望在数据库中只保存一个值。然而,我最终保存了2个员工记录。

实体编码如下

    @Entity
    @Table(name = "employee")
    public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "employee_id")
    private Long employeeId;

    @Column(name = "employeehexa_id") 
    private String _id;

    @Override
    public int hashCode() {
        HashCodeBuilder hcb = new HashCodeBuilder();
        hcb.append(_id);
        return hcb.toHashCode();
    }   


    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Employee)) {
            return false;
        }
        Employee that = (Employee) obj;
        EqualsBuilder eb = new EqualsBuilder();
        eb.append(_id, that._id);
        return eb.isEquals();
    }

    // Required Constructors, getters, setters not shown for brevity
   }

下面是我保存两个具有相同ID的对象的调用

@Autowired
private EmployeeRepo employeeRepo;

@RequestMapping("/test")
String Test() throws Exception {

    Employee e1 = new Employee("111");
    Employee e2 = new Employee("111");
     System.out.println(e1.equals(e2)); // prints true, implying hashcode and equals working fine
    employeeRepo.save(e1);
    employeeRepo.save(e2);//Both e1 and e2 are saved inspite of being equal

    return "Completed !";
}

平等检查似乎运作良好。是spring JPararePository的save()有什么原因导致了这个问题,还是我对Equality/HashCode契约是如何强制的理解不正确?

我以为我理解了equality/hashcode,但看起来并非如此。感谢任何帮助。THX.

共有1个答案

吕宸
2023-03-14

根据这个答案https://stackoverflow.com/a/11881628/5695673,您可能有两个记录,因为您的字段employeeID对于您的实体是不同的,所以对于spring-data,这两个实体是不同的。
测试您的equals()/hashcode()是否按预期工作,您可以尝试将您的实体放在一个检查对象相等性的集合中(即set),并尝试一次保存所有集合。

示例:

Set<Employee> employees = new HashSet<Employee>();
employees.add( new Employee("111"));
employees.add( new Employee("111"));

System.out.println(employees.size()); //1
employeeRepo.save(employees); // 1 record

更多信息请访问:https://developer.jboss.org/wiki/equalsandhashcode?_sscc=t

 类似资料:
  • 菜单栏: Code —> Generate —> equals() and hashCode() 右键菜单:Generate —> equals() and hashCode() 快捷键: Mac: command + N Windows\/Linux: Alt + Insert —> equals() and hashCode()

  • 如果你有如下需求,你必须重载 equals() 和 hashCode() 方法: 想把持久类的实例放入 Set 中(当表示多值关联时,推荐这么做),而且 想重用脱管实例 Hibernate 保证,仅在特定会话范围内,持久化标识(数据库的行)和 Java 标识是等价的。因此,一旦我们混合了从不同会话中获取的实例,如果希望 Set 有明确的语义,就必须实现 equals() 和 hashCode()。

  • 本文向大家介绍hashCode 与 equals ?为什么重写equals时必须重写hashCode方法?相关面试题,主要包含被问及hashCode 与 equals ?为什么重写equals时必须重写hashCode方法?时的应答技巧和注意事项,需要的朋友参考一下 面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” ha

  • 问题内容: 我应该如何实施和在Java下面的类? 问题答案: 在Eclipse中,右键单击->源->生成hashCode(),然后equals()给出以下信息: 我已选择代码作为唯一字段

  • 我正在Java开发一个纸牌游戏,我试图比较hashMap中的键和ArrayList中的元素(两者都是对象)。hashCode()和equals()被重写,但出现了一个错误,我不确定它的哪一部分是错误的。 这是纸牌课 我们要做的比较 错误:点击查看错误图片

  • UISegmentedControl似乎增加了一些额外的高度。我创建了一个UIView(绿色)和一个UISegmentedControl,其中我将两者的高度限制设置为56。它们应该显示相同的高度,但高度似乎略有不同。结果在模拟器中 以下是IB的约束。约束