在 JPA/Hibernate 中为没有业务键的浅层 class 层次结构提供 object 相等性
Providing object equality for a shallow class hierarchy with no business keys in JPA/Hibernate
我确定标题可以改进,这样这个问题可能对更广泛的受众有用,但我不确定如何改进。
我正在做一个小型测试项目,试图为表示在服务器和客户端之间交换的消息的实体提供 JPA/Hibernate 持久性(表示消息的 classes 在两个应用程序,但只有服务器 decoded/encoded 的应用程序将被保留。
协议支持三种类型的交换:
- 向服务器发送文本,服务器回复 ACK 消息。
- 向服务器发送一些杂项信息,服务器以与上面相同的 ACK 消息格式回复。
- 向服务器发送带有时区的 date/time 请求,服务器回复该时区的当前 date/time。
所有消息都具有相同的 header 和页脚格式(特别是 header 具有消息类型标识符,页脚具有校验和字段),以及提到的有效载荷,这可能是在来自同一类型的不同消息之间重复,因此它们不足以从持久性上下文中唯一标识给定类型的消息。
请注意,header和页脚信息仅与传输上下文相关,因此不需要对它们进行持久化,仅针对各自的有效载荷和一些persistence-related,唯一标识消息ID。
我想出了一个 class 设计,其中包含一个抽象基础 class 以及每个消息类型的一个子 class(因此有五个不同的 final
subclasses),每个都有它们的有效载荷字段。基本 class 除了可能的 persistence-related id 字段之外没有其他字段,以便在数据库中唯一标识消息。
我知道我需要为它们提供适当的 equals()
和 hashCode()
实现,既是为了将它们添加到 memory-based collections 又是为了持久化它们。
我已经决定,此层次结构的最佳 O-R 映射是 JOINED
继承策略,它将基本消息 table 与包含的单个消息 table 连接起来各自的有效载荷字段。所以基本消息 table 将有一个 auto-generated 主键,它将被映射到抽象消息的 id。
题目其实是two-fold。基本上,我想知道对于这种情况,哪种 equals()
和 hashCode()
实施方法更可取,但如果有人担心 class 设计和选择的继承策略,我也请问是否可以让我知道。
因此,为了将其变成一个有用的问题,我基本上是在问,在没有原始 self-identifying 的实体的情况下,我应该如何覆盖 equals()
和 hashCode()
( "business key") 字段,它们都继承自相同的抽象基 class,它可能包含一个 persistence-based 标识符字段。
我打算将其设计为支持具有较新消息类型的较新协议,不一定来自相同的基础class(除非我可以将其设为非常通用的基础class)。
除非您必须查询所有消息,否则我根本不会使用继承映射。在您的情况下,由于您共享的属性很少,因此最好使用 TABLE_PER_CLASS 策略。
除此之外,我建议您始终根据生成的主键序列实施 equals/hashCode。如果您将新实体(即没有 id 的实体)放入基于散列的集合中,持久化它们然后继续使用基于散列的集合,则此方法只是一个问题。如果不是这种情况,只使用 equals/hashCode.
的主键绝对没问题
我确定标题可以改进,这样这个问题可能对更广泛的受众有用,但我不确定如何改进。
我正在做一个小型测试项目,试图为表示在服务器和客户端之间交换的消息的实体提供 JPA/Hibernate 持久性(表示消息的 classes 在两个应用程序,但只有服务器 decoded/encoded 的应用程序将被保留。
协议支持三种类型的交换:
- 向服务器发送文本,服务器回复 ACK 消息。
- 向服务器发送一些杂项信息,服务器以与上面相同的 ACK 消息格式回复。
- 向服务器发送带有时区的 date/time 请求,服务器回复该时区的当前 date/time。
所有消息都具有相同的 header 和页脚格式(特别是 header 具有消息类型标识符,页脚具有校验和字段),以及提到的有效载荷,这可能是在来自同一类型的不同消息之间重复,因此它们不足以从持久性上下文中唯一标识给定类型的消息。
请注意,header和页脚信息仅与传输上下文相关,因此不需要对它们进行持久化,仅针对各自的有效载荷和一些persistence-related,唯一标识消息ID。
我想出了一个 class 设计,其中包含一个抽象基础 class 以及每个消息类型的一个子 class(因此有五个不同的 final
subclasses),每个都有它们的有效载荷字段。基本 class 除了可能的 persistence-related id 字段之外没有其他字段,以便在数据库中唯一标识消息。
我知道我需要为它们提供适当的 equals()
和 hashCode()
实现,既是为了将它们添加到 memory-based collections 又是为了持久化它们。
我已经决定,此层次结构的最佳 O-R 映射是 JOINED
继承策略,它将基本消息 table 与包含的单个消息 table 连接起来各自的有效载荷字段。所以基本消息 table 将有一个 auto-generated 主键,它将被映射到抽象消息的 id。
题目其实是two-fold。基本上,我想知道对于这种情况,哪种 equals()
和 hashCode()
实施方法更可取,但如果有人担心 class 设计和选择的继承策略,我也请问是否可以让我知道。
因此,为了将其变成一个有用的问题,我基本上是在问,在没有原始 self-identifying 的实体的情况下,我应该如何覆盖 equals()
和 hashCode()
( "business key") 字段,它们都继承自相同的抽象基 class,它可能包含一个 persistence-based 标识符字段。
我打算将其设计为支持具有较新消息类型的较新协议,不一定来自相同的基础class(除非我可以将其设为非常通用的基础class)。
除非您必须查询所有消息,否则我根本不会使用继承映射。在您的情况下,由于您共享的属性很少,因此最好使用 TABLE_PER_CLASS 策略。
除此之外,我建议您始终根据生成的主键序列实施 equals/hashCode。如果您将新实体(即没有 id 的实体)放入基于散列的集合中,持久化它们然后继续使用基于散列的集合,则此方法只是一个问题。如果不是这种情况,只使用 equals/hashCode.
的主键绝对没问题