currently we’re having a problem calling remove on a PersistentSet after the entity containing that set was serialized/deserialized during the server to client transfer.
We’re using an entity Item which has an id (generated seq), a name (NaturalId) and a set with Labels.
The entity Label has an id (generated seq), language (NaturalId), text and (bidirectional) the item (NaturalId) it belongs to.
the hashcode and equals methods use the NaturalIds of the entities:
hashcode for Label: Objects.hash(getLanguage(), getItem());
hashcode for Item: Objects.hash(getName());
During deserialization of Item the PersistentSet of the labels is incorrectly written, due to Label.item for some reason being null (or partly initialised), which leads to a different hashcode than it should be.
This then leads to Item.removeLabel(lbl) not working, because the Label used for removal has the Item set, leading to another calculated hashcode.
Code snippet of the example below:
// simulate server to client transfer Item clientItem = (Item) copyObjectBySerialization(item); Set<Label> clientSet = (Set<Label>) copyObjectBySerialization(item.getLabel()); // just get the first label Label label = (Label) clientItem.getLabel().toArray(); // remove does not work on the deserialized item System.out.println(clientItem.removeLabel(label)); // works when the set gets 'reset' Set<Label> labels = new HashSet<>(clientItem.getLabel()); clientItem.setLabel(labels); System.out.println(clientItem.removeLabel(label)); // works when calling remove on deserialized set System.out.println(clientSet.remove(label));
A demo code can be found here https://www.magentacloud.de/lnk/jWm4jO4b
So is there any way to fix the issue, are we maybe supposed to write customized readObject/writeObject methods for all of our entity classes?
Hibernate Version used: 5.2.17
Java Version: 8u152 and 8u172
Hope you can help me out,