假设我们有以下JPA实体:
假设我们可以通过父项上的名称(两者的组合)唯一地识别一个子项。因此,父项和名称可以被视为子项的业务键。
我现在不确定在类Child上实现equals(和hashCode)的最佳方法是什么。
引用应用程序的ID
由于应用程序代理将被加载并且其ID将设置在代理上,因此应用程序实体本身不会被初始化:
其次(较小的缺点),这将需要Hibernate访问属性而不是字段;因此,我需要在getter上设置注释,而不是在字段上设置注释。对我个人来说,这是可以接受的,但当前项目的习惯是在字段级别上放置注释。 不要使用引用实体来评估相等性 好的,但那么我需要其他东西。我不想使用Child的ID(不良做法),这只留下了一个选择:使用单独的属性,如UUID。我并不反对使用UUID,但前提是没有其他可用的选项。
我的问题是:
class Parent {
@Id
private Long id;
}
class Child {
@Id
private Long id;
@Column
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
}
假设我们可以通过父项上的名称(两者的组合)唯一地识别一个子项。因此,父项和名称可以被视为子项的业务键。
我现在不确定在类Child上实现equals(和hashCode)的最佳方法是什么。
引用应用程序的ID
由于应用程序代理将被加载并且其ID将设置在代理上,因此应用程序实体本身不会被初始化:
这样做可以解决问题,但我也看到了一些缺点。首先(较小的缺点),在父对象上增加一个额外的非null检查可能是明智的,这会使您的equals方法更简单。
public boolean equals (Object o) { //null check, instanceof check ... return new EqualsBuilder().append(getName(), other.getName()) .append(getParent().getId(), other.getParent().getId()) .isEquals();
}
其次(较小的缺点),这将需要Hibernate访问属性而不是字段;因此,我需要在getter上设置注释,而不是在字段上设置注释。对我个人来说,这是可以接受的,但当前项目的习惯是在字段级别上放置注释。 不要使用引用实体来评估相等性 好的,但那么我需要其他东西。我不想使用Child的ID(不良做法),这只留下了一个选择:使用单独的属性,如UUID。我并不反对使用UUID,但前提是没有其他可用的选项。
我的问题是:
- 我错过了其他的选项吗?
- 在您的意见中,建议采用什么方式?