Java 实体和值对象的相等性
所以我读过 有效Java:第3章。所有对象通用的方法(多年来很多:) 和Erich Evans的DDD(多年来很多:) 在使用对象的内部状态/数据为实体和值类型编写equals函数时,始终遵循比较ID的约定。因此,现在我们面临一个新的挑战,即我们有一个应用程序,该应用程序具有一个现有的富域模型,应该在将来持久化。关于这一点,我有一个非常具体的问题,我遇到了一些代码编写程序阻塞。其中有几个类与各种信息片段没有标识。。。一个典型的值对象,你可能会说。。。但也有对其他子对象(即对象图)的引用。所以通常是这样的:Java 实体和值对象的相等性,java,Java,所以我读过 有效Java:第3章。所有对象通用的方法(多年来很多:) 和Erich Evans的DDD(多年来很多:) 在使用对象的内部状态/数据为实体和值类型编写equals函数时,始终遵循比较ID的约定。因此,现在我们面临一个新的挑战,即我们有一个应用程序,该应用程序具有一个现有的富域模型,应该在将来持久化。关于这一点,我有一个非常具体的问题,我遇到了一些代码编写程序阻塞。其中有几个类与各种信息片段没有标识。。。一个典型的值对象,你可能会说。。。但也有对其他子对象(即对象图)的引用。所以通常
public class BeeskneesEntityA {
private Long id;
private Voj childV;
}
public class Voj {
private Long priceInCents;
private Long otherLong;
private BeeskneesEntityB childB;
}
public class BeeskneesEntityB {
private Long id;
...
}
使用
id
来确定平等性是有史以来最糟糕的想法。您可以有两个equal
对象,一个已经持久化(具有id),另一个处于瞬态(没有id)。如果根据id确定相等性,则它们将被视为不同的,即使它们不是。请记住,equal
意味着equal
——既不是同一对象,也不是同一来源的对象。此外,如果您对加载的对象(id为)进行了修改,则此对象不应再等于具有相同id但具有原始属性的任何其他对象。您可以使用id!。这完全取决于equals对对象的意义。例如,在用户对象列表中,如果用户名与用户名相同,则两个对象可以相等。对于两个D/T用户来说,不能使用相同的用户名。@ DeGeNoSW使用<代码> ID <代码>作为<代码>的唯一属性等于方法创建了许多需要处理的麻烦:不能将2个或多个未保存实例添加到集合或hashmap,因为它们被认为是相等的,因此覆盖了另一个实例。如果你有一些批量编辑,你需要手动检测更改,而不是使用equals
查找更改的实例,并根据不相等性执行选择性更新。相关:我绝对不同意这是有史以来最糟糕的想法。在许多情况下(想象一个需要持久化的实体,它有2个任意浮点数和另一个表的外键),这是唯一可能的解决方案。但我不想在这里讨论这个问题,这不是问题所在。使用id
来确定平等性是有史以来最糟糕的想法。您可以有两个equal
对象,一个已经持久化(具有id),另一个处于瞬态(没有id)。如果根据id确定相等性,则它们将被视为不同的,即使它们不是。请记住,equal
意味着equal
——既不是同一对象,也不是同一来源的对象。此外,如果您对加载的对象(id为)进行了修改,则此对象不应再等于具有相同id但具有原始属性的任何其他对象。您可以使用id!。这完全取决于equals对对象的意义。例如,在用户对象列表中,如果用户名与用户名相同,则两个对象可以相等。对于两个D/T用户来说,不能使用相同的用户名。@ DeGeNoSW使用<代码> ID <代码>作为<代码>的唯一属性等于方法创建了许多需要处理的麻烦:不能将2个或多个未保存实例添加到集合或hashmap,因为它们被认为是相等的,因此覆盖了另一个实例。如果你有一些批量编辑,你需要手动检测更改,而不是使用equals
查找更改的实例,并根据不相等性执行选择性更新。相关:我绝对不同意这是有史以来最糟糕的想法。在许多情况下(想象一个需要持久化的实体,它有2个任意浮点数和另一个表的外键),这是唯一可能的解决方案。但我不想在这里讨论这个问题,这不是问题所在。