Issue
I'm sure the title can be improved so this question may become useful to a wider audience, but I'm not sure how.
I'm working on a small test project trying to provide JPA/Hibernate persistence to entities representing messages that are exchanged between a server and a client (the classes representing the messages are reused between both applications, but only the ones decoded/encoded by the server will be persisted).
The protocol supports three types of exchanges:
- Sending a text to the server, which replies with an ACK message.
- Sending some miscellaneous info to the server, which replies with the same ACK message format from above.
- Sending a date/time request with a time zone to the server, which replies with the current date/time in that timezone.
All messages have the same header and footer format (in particular the header has a message type identifier and the footer has a checksum field), along with the mentioned payloads, which may be repeated among different messages from the same type, so they are not enough to uniquely identify a message of a given type from a persistence context.
Note that header and footer information is only relevant for the transmission context, so no persisting is required for them, only for the respective payloads and some persistence-related, uniquely identifying message id.
I've come up with a class design consisting of an abstract base class as well as one subclass for each message type (thus five distinct final
subclasses), each of them with their payload fields. The base class has no fields besides a possible persistence-related id field in order to uniquely identify the message in the database.
I understand I need to provide proper equals()
and hashCode()
implementations for them, both for adding them to memory-based collections and for persisting them.
I've decided that the best O-R mapping for this hierarchy is a JOINED
inheritance strategy which joins a base message table with individual message tables containing the respective payload fields. So the base message table will have an auto-generated primary key that is going to be mapped to the abstract message's id.
The question is two-fold actually. Basically I want to know how which should be the preferable equals()
and hashCode()
implementation approach for this scenario, but also in the case someone has concerns regarding the class design and chosen inheritance strategy, I'd ask if possible to let me know as well.
So in order to turn this into a useful question, I'm basically asking how should I override equals()
and hashCode()
in the case of entities with no original self-identifying ("business key") fields, all of them inheriting from the same abstract base class, which could contain a persistence-based identifier field.
I intend to design this to support newer protocols with newer message types, not necessarily from the same base class (unless I can make it a very general base class).
Solution
Unless you have to query all messages, I wouldn't use an inheritance mapping at all. In your case, since you share so few properties, it's probably best if you use the TABLE_PER_CLASS strategy.
Apart from that, I would recommend you always implement equals/hashCode based on the generated primary key sequence. This approach is only a problem if you put new entities i.e. without an id into hash based collections, persist them and then keep on using the hash based collection. If that is not the case, it's absolutely fine to just use the primary key for equals/hashCode.
Answered By - Christian Beikov
Answer Checked By - Marilyn (JavaFixing Volunteer)