Un'applicazione su cui sto lavorando utilizza Hibernate esclusivamente per recuperare una serie di oggetti persistenti da un database alla memoria. L'applicazione deve aggiornare questa istantanea in memoria dal database di tanto in tanto e questa dovrebbe essere l'unica comunicazione con il database.Come posso caricare un set Hibernate mappato come un set non modificabile?
Gli oggetti in memoria vengono quindi utilizzati per una serie di calcoli. I calcoli non devono modificare questi oggetti. Tranne qualche classe da qualche parte accidentalmente, e ho dovuto trascorrere un giorno a caccia dell'errore. Ora mi chiedo quale sia il modo migliore per rendere immutabile l'intero albero degli oggetti.
Supponiamo che la gerarchia delle classi si presenta così:
public class Building { // persistent entity
private String name; // hibernate-mapped property
private Set<Person> inhabitants; // hibernate-mapped collection
// getters
}
public class Person { // persistent entity
private String name; // hibernate-mapped property
// getters
}
ho impedito clienti di accedere al database:
- avidamente il recupero tutte le entità e le collezioni
- marcatura tutti gli enti e collezioni con
mutable=false
nei mapping Hibernate - non fornisce alcuna istanza della sessione di Hibernate, o modifica dello stato metodi g dao.
Ora l'errore che vorrei evitare è che qualcuno accidentalmente sta andando building.getInhabitants().clear();
. Mi vengono in mente queste opzioni:
Getter avvolgendo: Fare
getInhabitants
primo avvolgimentoinhabitants
in una chiamataCollections.unmodifiableSet()
, poi restituirlo.- Pro: Almeno il lavoro, il codice almeno più
- Contro: Feels hacky
classi wrapper: Rinominare
Building
-MutableBuilding
,Person
-MutablePerson
, e forniscono le classi immutabiliBuilding
ePerson
. Poiché la mia applicazione ha un chiaro punto di istantanea, posso recuperare i record come oggetti mutabili (come faccio ora), creare copie immutabili e presentare l'albero degli oggetti ai client.- Pro: Dritto java, nessuna magia di ibernazione. Uso la mia parola chiave preferita:
final
- Contro: Più codice da scrivere e gestire. Inoltre, Hibernate mantiene le istanze mutabili in memoria?
- Pro: Dritto java, nessuna magia di ibernazione. Uso la mia parola chiave preferita:
Hibernate mappatura magica: usare quella parola chiave magica per istruire Hibernate per avvolgere le collezioni che tramonta sui miei oggetti entità in
Collections.unmodifiableSet()
o equivalente.(Nota: io uso un file di mapping XML)- Pro: Elegante, senza codice aggiuntivo
- Contro: Tale parola chiave potrebbero non esistere
Hibernate estensione: utilizzare quella estensione Hibernate punto di scrivere il mio istanziatore di oggetto, e lì avvolgere il set in
Collections.unmodifiableSet()
prima di restituirlo.- Pro: più elegante di hacker miei getter
- Contro: Tale punto di estensione non può esistere
In questo momento sto appoggiato verso # 2, soprattutto perché non lo faccio sapere se 3 e 4 sono possibili.
Qual è il modo migliore?
+1 per avermi ricordato perché scriviamo getter e setter :-) – KarlP
Questa sembra la soluzione migliore. Dovrò solo fare i conti con il fatto che a volte le classi mutevoli sono a posto! :) – oksayt