微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 JPA/Hibernate 中为没有业务键的浅层类层次结构提供对象相等

如何解决在 JPA/Hibernate 中为没有业务键的浅层类层次结构提供对象相等

我确信标题可以改进,因此这个问题可能对更广泛的受众有用,但我不确定如何改进。

我正在做一个小型测试项目,试图为表示在服务器和客户端之间交换的消息的实体提供 JPA/Hibernate 持久性(表示消息的类在两个应用程序之间重用,但只有解码的类/由服务器编码将被持久化)。

该协议支持三种类型的交换:

  • 向服务器发送文本,服务器回复 ACK 消息。
  • 向服务器发送一些杂项信息,服务器使用与上面相同的 ACK 消息格式进行回复
  • 向服务器发送带有时区的日期/时间请求,服务器使用该时区的当前日期/时间进行回复

所有消息都具有相同的头部和尾部格式(特别是头部有一个消息类型标识符,尾部有一个校验和字段),以及提到的有效载荷,它们可能在来自相同类型的不同消息中重复,所以它们不足以从持久化上下文中唯一标识给定类型的消息。

请注意,页眉和页脚信息仅与传输上下文相关,因此不需要对它们进行持久化,只需要针对各自的有效负载和一些与持久化相关的唯一标识消息 ID。

我提出了一个类设计,其中包含一个抽象基类以及每个消息类型的一个子类(因此有五个不同的 final 子类),每个子类都有其有效负载字段。除了可能与持久性相关的 id 字段外,基类没有其他字段,以便唯一标识数据库中的消息。

我知道我需要为它们提供适当的 equals()hashCode() 实现,以便将它们添加到基于内存的集合中并持久化它们。

我已决定此层次结构的最佳 O-R 映射是 JOINED 继承策略,它将基本消息表与包含相应负载字段的单个消息表连接起来。因此,基本消息表将有一个自动生成的主键,该主键将映射到抽象消息的 id。

问题实际上有两个方面。基本上我想知道对于这种情况,哪一种应该是更可取的 equals()hashCode() 实现方法,但如果有人对类设计和选择的继承策略有疑虑,我会问也可以让我知道。

因此,为了将其转化为一个有用的问题,我基本上是问在没有原始自我标识(“业务密钥”)的实体的情况下,我应该如何覆盖 equals()hashCode() ) 字段,它们都继承自同一个抽象基类,该类可以包含一个基于持久性的标识符字段。

我打算将其设计为支持具有较新消息类型的较新协议,不一定来自相同的基类(除非我可以使其成为非常通用的基类)。

解决方法

除非您必须查询所有消息,否则我根本不会使用继承映射。就您而言,由于您共享的属性很少,因此最好使用 TABLE_PER_CLASS 策略。

除此之外,我建议您始终根据生成的主键序列实现 equals/hashCode。如果您将新实体(即没有 id 的实体)放入基于散列的集合中,将它们持久化,然后继续使用基于散列的集合,则此方法仅是一个问题。如果不是这种情况,只对 equals/hashCode 使用主键绝对没问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。