Mejores Prácticas
Escribe clase finamente granularizadas y mapealas usando <component>.
Usa una clase Dirección para encapsular calle,
distrito, estado, código postal.
Esto alienta la reutilización de código y simplifica el refactoring.
Declara las propiedades identificadoras en clases persistentes.
Hibernate hace opcionales las propiedades identificadoras. Existen todo tipo de razones
por las que debes usarlas. Recomendamos que los identificadores sean 'sintéticos'
(generados, sin ningún significado de negocio).
Identifica las claves naturales.
Identifica las claves naturales de todas las entidades, y mapealas usando
<natural-id>. Implementa equals() y
hashCode() para comparar las propiedades que componen la clave natural.
Coloca cada mapeo de clase en su propio fichero.
No uses un solo documento monolítico de mapeo. Mapea com.eg.Foo en
el fichero com/eg/Foo.hbm.xml. Esto tiene sentido particularmente en un
ambiente de equipo.
Carga los mapeos como recursos.
Despliega los mapeos junto a las clases que mapean.
Considera externalizar las cadenas de consulta.
Esta es una buena práctica si tus consultas llaman a funciones SQL que no son del
estándar ANSI. Externalizar las cadenas de consulta a ficheros de mapeo hará la
aplicación más portable.
Usa variables de ligado.
Igual que en JDBC, siempre remplaza valores no constantes con "?". ¡Nunca uses manipulación
de cadenas para ligar un valor no constante en una consulta! Incluso mejor, considera usar
parámetros con nombre en las consultas.
No manejes tus propias conexiones JDBC.
Hibernate deja a la aplicación administre las conexiones JDBC. Este enfoque debe considerarse
como último recurso. Si no puedes usar los provedores de conexión prefabricados, considera
prover tu propia implementación de org.hibernate.connection.ConnectionProvider.
Considera usar un tipo personalizado.
Supón que tienes un tipo Java, digamos de alguna biblioteca, que necesita hacerse persistente
pero no provee los métodos de acceso necesarios para mapearlo como un componente. Debes considerar
implementar org.hibernate.UserType. Este enfoque libera al código de aplicación
de implementar transformaciones a / desde un tipo Hibernate.
Usa JDBC codificado a mano en cuellos de botella.
En áreas del sistema de rendimiento crítico, algunos tipos de operaciones podrían beneficiarse
del JDBC directo. Pero por favor, espero hasta que sepas que algo es
un cuello de botella. Y no asumas que el JDBC directo es necesariamente más rápido. Si necesitas
usar JDBC directo, podría ser valioso abrir una Session de Hibernate y usar esa
conexión JDBC. De esta forma puedes usar aún la misma estrategia de transacción y el mismo
proveedor de conexiones subyacente.
Comprende la limpieza (flushing) de Session.
De vez en cuando la sesión sincroniza su estado persistente con la base de datos. El rendimiento
se verá afectado si este proceso ocurre demasiado frecuentemente. A veces puedes minimizar
limpieza innecesaria deshabilitando la limpieza automática o incluso cambiando el orden de las
consultas u otras operaciones en una transacción en particular.
En una aplicación en tres gradas, considera usar objetos separados.
Al usar una arquitectura de servlet / sesión, puedes pasar objetos persistentes en el bean de
sesión hacia y desde la capa de servlet / JSP. Usa una sesión nueva para atender el servicio de cada
petición. Usa Session.merge() o Session.saveOrUpdate() para
sincronizar los objetos con la base de datos.
En una arquitectura en dos gradas, considera usar contexto de persistencia largos.
Las transacciones de base de datos tienen que ser tan cortas como sea posible. Sin embargo,
frecuentemente es necesario implementar transacciones de aplicación
ejecutándose en largo, una sola unidad de trabajo desde el punto de vista de un usuario.
Una transacción de aplicación puede abarcar muchos ciclos petición/respuesta del cliente.
Es común usar objetos separados para implementar transacciones de aplicación. Una alternativa,
extremadamente apropiada en arquitecturas en dos gradas, es mantener un solo contacto de persistencia
abierto (sesión) para todo el ciclo de vida de la transacción de aplicación y simplemente
desconectar de la conexión JDBC al final de cada petición, y reconectar al comienzo de la
petición subsecuente. Nunca compartas una única sesión a través de más de una transacción
de aplicación, o estarás trabajando con datos aƱejos.
No trates la excepciones como recuperables.
Esto es más una práctica necesaria que una "mejor" práctica. Cuando ocurra una excepción,
deshaz (rollback) la Transaction y cierra la Session.
Si no lo haces, Hibernate no puede garantizar que el estado en memoria representa con exactitud
el estado persistente. Como un caso especial de esto, no uses Session.load()
para determinar si una instancia con el identificador dado existe en la base de datos. En cambio,
usa Session.get() o una consulta.
Prefiere la recuperación perezosa para las asociaciones.
Usa escasamente la recuperación temprana. Usa proxies y colecciones perezosas para la mayoría
de asociaciones a clases probablemente no estén mantenidas en el caché de segundo nivel. Para
las asociaciones a clases en caché, donde hay una probabilidad de acceso a caché extremadamente
alta, deshabilita explícitamente la recuperación temprana usando lazy="false".
Cuando sea apropiada la recuperación por unión (join fetching) para un caso de uso en particular,
usa una consulta con un left join fetch.
Usa el patrón sesión abierta en vista, o una fase de ensamblado
disciplinada para evitar problemas con datos no recuperados.
Hibernate liberal al desarrollador de escribir Objetos de Transferencia de Datos
(Data Transfer Objects) (DTO). En una arquitectura tradicional de EJB, los DTOs tienen
un propósito doble: primero, atacan el problema que los beans de entidad no son serializables.
Segundo, definen implícitamente una fase de ensamblado cuando se recuperan y se forman (marshalling)
todos los datos a usar por la vista en los DTOs antes de devolver el control a la grada de
presentación. Hibernate elimina el primer propósito. Sin embargo, aún necesitas una fase
de ensamblado (piensa en tus métodos de negocio como si tuviesen un contrato estricto con la grada
de presentación sobre qué datos están disponibles en los objetos separados) a menos que estés
preparado para tener el contexto de persistencia (la sesión) abierto a través del proceso
de renderización de la vista. ¡Esta no es una limitación de Hibernate! Es un requerimiento
fundamental de acceso seguro a datos transaccionales.
Considera abstraer tu lógica de negocio de Hibernate
Oculta el código de acceso a datos (Hibernate) detrás de una interface. Combina los patrones
DAO y Sesión de Hebra Local. Incluso puedes tener
algunas clases hechas persistentes por JDBC escrito a mano, asociadas a Hibernate por medio
de un UserType. (Este consejo está pensado para aplicaciones "suficientemente
grandes"; ¡no es apropiado para una aplicación con cinco tablas!)
No uses mapeos de asociación exóticos.
Son raros los casos de uso de asociaciones reales muchos-a-muchos. La mayor parte del tiempo
necesitas información adicional almacenada en una "tabla de enlace". En este caso, es mucho
mejor usar dos asociaciones uno-a-muchos a una clase de enlace intermedia. De hecho, pensamos
que la mayoría de asociaciones son uno-a-muchos y muchos-a-uno, debes ser cuidadoso al usr
cualquier otro estilo de asociación y preguntarte si es realmente necesario.
Prefiere las asociaciones bidireccionales.
Las asociaciones unidireccionales son más difíciles de consultar. En una aplicación grande,
casi todas las asociaciones deben ser navegables en ambas direcciones en consultas.