Usate una classe Address (indirizzo) per incapsulare street (via), suburb (comune), state (stato), postcode (codice postale). Questa pratica facilita il riuso del codice e la sua ristrutturazione (refactoring).
In Hibernate le proprietà di identificazione sono opzionali, tuttavia ci sono molte buone ragioni per cui è preferibile utilizzarle. Raccomandiamo che gli identificatori siano 'sintetici' (ovvero generati, senza altro significato applicativo), e di un tipo non-primitivo. Per la massima flessibilità usate java.lang.Long o java.lang.String.
Non usate un unico documento di mappaggio monolitico. Mappate com.eg.Foo nel file com/eg/Foo.hbm.xml. Questo è particolarmente utile nel lavoro di gruppo.
Distribuite i mappaggi insieme alle classi che mappano.
Questa è una buona pratica in particolare se le vostre interrogazioni chiamano delle funzioni SQL non ansi-standard. Esternalizzare le stringhe nei file di mappaggio renderà l'applicazione più portabile.
Come in JDBC, sostituite sempre i valori non constanti con "?" nelle query.Non usate mai manipolazione di stringhe per sostituire un valore non costante in una interrogazione! È anche meglio prendere in considerazione l'uso di parametri con nome, nelle interrogazioni.
Hibernate permette all'applicazione di gestire le connessioni JDBC. Questo approccio dovrebbe essere considerato un'ultima spiaggia. Se non potete usare i fornitori di connessione predefiniti, considerate la possibilità di implementare voi stessi l'interfaccia net.sf.hibernate.connection.ConnectionProvider.
Immaginate di avere un tipo di oggetto java, ad esempio proveniente da una libreria, che abbia bisogno di essere reso persistente, ma non fornisca i metodi di accesso necessari per mapparlo come un componente. Dovreste valutare la possibilità di implementare net.sf.hibernate.UserType. Questo approccio libera il codice applicativo dalla necessità di implementare trasformazioni da/a un tipo di Hibernate.
Nelle aree critiche rispetto alle performance del sistema, alcune operazioni (ad esempio cancellazioni o aggiornamenti massicci) potrebbero beneficiare da un'implementazione diretta in JDBC. Ma vi preghiamo di attendere fino a che non sappiate con certezza che qualcosa è un collo di bottiglia. Non assumete inoltre, che il JDBC diretto sia necessariamente più veloce: se avete bisogno di usarlo, potrebbe essere sensato aprire una Session di Hibernate e usare la sottostante connessione SQL. In questo modo potete comunque usare la stessa strategia transazionale e il fornitore di connessioni sottostante.
Di tanto in tanto la Session sincronizza il suo stato persistente con il database. Le performance saranno coinvolte se questo processo capita troppo spesso. Potete a volte minimizzare la quantità di scaricamenti non necessari disabilitando i meccanismi automatici, o anche cambiando l'ordine delle interrogazioni e delle altre operazioni all'interno di una particolare transazione.
Quando usate una architettura basata su servlet / session bean, potreste passare gli oggetti persistenti caricati nel session bean da e al servlet o allo strato delle jep. Usate una nuova sessione per gestire ogni richiesta. Usate poi Session.update() o Session.saveOrUpdate() per aggiornare lo stato persistente di un oggetto.
Quando usate solo un servlet, potete riutilizzare la stessa sessione per richieste multiple dei client. Semplicemente ricordate di sconnettere la sessione prima di restituire il controllo al client.
Questa, più che una migliore pratica, è una pratica necessaria. Quando capita un'eccezione, fate il rollback della Transaction e chiudete la Session. Se non lo fate, Hibernate non può garantire che lo stato in memoria rappresenti accuratamente lo stato persistente. Come caso particolare, non usate Session.load() per determinare se un'istanza con quel particolare identificatore esista sul database; usate find(), invece.
Usate con moderazione il caricamento diretto (via outer-join). Usate i mediatori (proxy) e/o le collezioni a caricamento differito per la maggior parte delle associazioni con classi che non siano messe in cache a livello della JVM. Per le associazioni con le classi in cache, dove ci sia un'alta possibilità di avere gli oggetti in cache disabilitate esplicitamente il caricamento diretto usando outer-join="false". Se in un particolare caso dovesse essere appropriato un caricamento diretto con outer-join, potete usare una interrogazione con un left join.
Mascherate il codice di accesso ai dati (via hibernate) dietro un'interfaccia. Combinate i pattern DAO e Thread Local Session. Potete anche avere alcune classi rese persistenti da codice JDBC manuale, associate ad Hibernate tramite uno UserType. (Questo consiglio ha senso per applicazioni "sufficientemente grandi", non è appropriato per un'applicazione con poche tabelle!)