2017-10-19 185 views
1

Kotlin有一个数据类,它自带toString(), equals(), hashCode(), and copy()可以使用Kotlin数据类equals()方法,而不需要与JPA一起进一步修改?

可以使用equals() and hashCode()“直接开箱即用”,无需进一步调整JPA类?我们通常感觉有信心,我们正在做正确的事情之前,要花费大量的时间在“自然键”,持久化上下文的生命周期等在下面链接的文章读了:

我们现在可以简单地依靠Kotlin的equals() and hashcode()实现吗?

+0

号的数据类的equals方法使用的所有字段,包括自动生成的ID,要比较的实体。 –

回答

3

在我看来,不应该使用Kotlin中的数据类,除非你真的明白你在做什么。

覆盖equals/hashCode关于可变数据可能会导致问题。 考虑你已经添加了一个可变类的实例HashSet,然后改变了一些,如果该实例的属性。 这会影响hashCode返回的值。

反过来,这使得HashSet找不到该实例,因为它会在完全不同的散列表条目中查找它。 您将无法从HashSet中删除此实例!

在kotlin中作为数据类的候选者的好例子是:复数,恒定大小的向量。不好的例子是:JPA实体,DTO。

至于JPA,这些文章都是有见地的。 还有另一种意见:根本不应该为JPA实体覆盖equalshashCode

理由:JPA提供商(休眠,的EclipseLink)必须保证a === b当且仅当a和b具有在表相同的主键,和a和b是在持久状态。 此合约可能会因分离实体而中断。 但是,在我看来,与分离实体合作是一个不好的做法,应该避免。 这种可能有意义的事情是将分离的实体存储在另一个JPA事务中。

1

JPA实体应该依赖于对象标识,而不是主键相等 - 这大概是对象关系映射的全部内容的90%。让JPA实现跳过各种循环来创建,维护和传播Identity Map,然后忽略它可能意味着您根本不需要JPA,并且会导致问题。特别是如果你不是100%知道你在做什么。

这就是说,也许你可以使用在许多情况下科特林数据类,但前提是:

  • 你不存储在地图持久化对象,并设置
  • 保持默认的构造函数和不尝试触摸对象初始化以任何方式(提供默认值等)
相关问题