Tiendo a usar Hibernate en combinación con el marco Spring y sus capacidades de demarcación de transacciones declarativas (por ejemplo, @Transactional ).
Como todos sabemos, hibernate intenta ser lo más no invasivo y transparente posible, sin embargo, esto resulta un poco más desafiante cuando se emplean lazy-loaded
relaciones.
Veo una serie de alternativas de diseño con diferentes niveles de transparencia.
- Haga relaciones no cargadas de pereza (p. Ej.,
fetchType=FetchType.EAGER)
- Esto viola toda la idea de carga diferida.
- Inicializar colecciones usando
Hibernate.initialize(proxyObj);
- Esto implica un acoplamiento relativamente alto al DAO
- Aunque podemos definir una interfaz con
initialize
, no se garantiza que otras implementaciones proporcionen un equivalente.
- Agregue el comportamiento de la transacción a los
Model
propios objetos persistentes (utilizando un proxy dinámico o@Transactional
)- No probé el enfoque de proxy dinámico, aunque nunca pareció que @Transactional funcionara en los objetos persistentes. Probablemente debido a que la hibernación es la operación en un proxy con el que estar.
- Pérdida de control cuando las transacciones realmente se están llevando a cabo.
- Proporcionar API perezosa / no perezosa, por ejemplo,
loadData()
yloadDataWithDeps()
- Obliga a la aplicación a saber cuándo emplear qué rutina, de nuevo acoplamiento estrecho
- Desbordamiento del método,,
loadDataWithA()
....,loadDataWithX()
- Forzar la búsqueda de dependencias, por ejemplo, proporcionando solo
byId()
operaciones- Requiere muchas rutinas no orientadas a objetos, por ejemplo
findZzzById(zid)
, y luego engetYyyIds(zid)
lugar dez.getY()
- Puede ser útil buscar cada objeto en una colección uno por uno si hay una gran sobrecarga de procesamiento entre las transacciones.
- Requiere muchas rutinas no orientadas a objetos, por ejemplo
- Haga parte de la aplicación @Transactional en lugar de solo el DAO
- Posibles consideraciones de transacciones anidadas
- Requiere rutinas adaptadas para la gestión de transacciones (p. Ej., Suficientemente pequeñas)
- Pequeño impacto programático, aunque puede resultar en grandes transacciones
- Proporcionar al DAO perfiles de búsqueda dinámicos , por ejemplo,
loadData(id, fetchProfile);
- Las aplicaciones deben saber qué perfil usar cuando
- Tipo de transacciones AoP, por ejemplo, interceptar operaciones y realizar transacciones cuando sea necesario
- Requiere manipulación de código de bytes o uso de proxy
- Pérdida de control cuando se realizan transacciones
- Magia negra, como siempre :)
¿Perdí alguna opción?
¿Cuál es su enfoque preferido cuando intenta minimizar el impacto de las lazy-loaded
relaciones en el diseño de su aplicación?
(Oh, y lo siento por WoT )