The main object:
@Entity public class KeyEntity { @Id @GeneratedValue(strategy = GenerationType.TABLE) public Long id; public String handle; public boolean equals(Object o) { KeyEntity oke = (KeyEntity) o; return handle != null ? handle.equals(oke.handle) : oke.handle == null; } public int hashCode() { return handle != null ? handle.hashCode() : 0; } }
Value:
@Entity public class ValueEntity { @Id @GeneratedValue(strategy = GenerationType.TABLE) public Long id; @ManyToOne public KeyEntity key; public String value; public boolean equals(Object o) { ValueEntity ove = (ValueEntity) o; return key != null ? key.equals(ove.key) : ove.key == null; } public int hashCode() { return key != null ? key.hashCode() : 0; } }
Container:
@Entity public class ContainerEntity { @Id @GeneratedValue(strategy = GenerationType.TABLE) public Long id; @OneToMany @MapKey(name = "key") public Map<KeyEntity, ValueEntity> values = new HashMap<KeyEntity, ValueEntity>(); }
Main:
KeyEntity k1 = new KeyEntity(); k1.handle = "k1"; em.persist(k1); KeyEntity k2 = new KeyEntity(); k2.handle = "k2"; em.persist(k2); ValueEntity v1 = new ValueEntity(); v1.key = k1; v1.value = "v1"; em.persist(v1); ValueEntity v2 = new ValueEntity(); v2.key = k2; v2.value = "v2"; em.persist(v2); ContainerEntity ce = new ContainerEntity(); ce.values.put(k1, v1); ce.values.put(k2, v2); em.persist(ce);
If I add several key-value pairs to ContainerEntity , and then reload the specified container, only one key-value pair will be present. If you look at the result of working on the main function, first type “2” and then “1”.
I see that this is due to KeyEntity.hashCode - when pasting into the HashMap KeyEntity.handle is null , so all pairs will have the same hash code. KeyEntity.id populated at this point - if I base the hash code on this field, everything will work. Also, if I change the key to String , it will be loaded on time for hashCode calls.
How to change my mappings in ContainerEntity so that KeyEntity.handle when it is placed inside the map, so hashCode can use it?
source share