chiave di entità:JPA Mappa w/Entità chiave e valore di entità
@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;
}
}
Valore Entità:
@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;
}
}
contenitore di entità:
@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>();
}
principale:
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);
// display number of values
System.out.println(ce.values.size());
// create new transaction
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
// find our container and inspect the number of values
ce = em.find(ContainerEntity.class, ce.id);
System.out.println(ce.values.size());
Se aggiungo più coppie chiave-valore a ContainerEntity
e quindi ricarico il contenitore, sarà presente una sola coppia chiave-valore. Se si guarda l'output di eseguire la funzione principale sopra, viene stampato prima '2', seguito da '1'.
posso vedere che questo è causa di KeyEntity.hashCode
- quando si inserisce nel HashMap
KeyEntity.handle
è null
, quindi tutte le coppie avranno lo stesso codice hash. KeyEntity.id
viene popolato a questo punto - se il codice hash viene disattivato da questo campo, tutto funziona. Inoltre, se cambio la chiave in modo che sia String
, viene caricata in tempo per le chiamate a hashCode
.
Come è possibile modificare le mie mappature in ContainerEntity
in modo che KeyEntity.handle
venga caricato quando viene inserito all'interno della mappa, quindi hashCode
può utilizzarlo?
Trovo che questo sia piuttosto strano. Perché il riferimento a gestire non fa scattare un carico dal database? Apprezzo che KeyEntity venga caricato pigramente, ma l'accesso a un campo dovrebbe svegliarlo! –