Wow, gran pregunta. No estoy seguro de que un simple mortal pueda responderlo. Pero creo que estás siendo demasiado rápido para descartar "la posibilidad de cambiar tu base de datos". Hay muchos paquetes de software, tanto comerciales como de código abierto, que ofrecen la posibilidad de trabajar con diferentes RDBMS como una tienda de respaldo. Administrar el SQL para implementar en más de 2 plataformas de base de datos puede convertirse en una pesadilla absoluta, por lo que tener algo construir su SQL de una manera predecible (al menos en comparación con tenerlo escrito a mano) es una gran ventaja. Solo jugando al defensor del diablo, para algunas plataformas de bases de datos pude ver un crecimiento en el rendimiento de las transacciones, lo que hace que una opción de base de datos también sea prohibitivamente cara. La mayoría de los ORM te ayudarán con esto de una manera u otra, aunque tener una API de consulta enriquecida puede ser de gran ayuda cuando las necesidades de tu base de datos son lo suficientemente complejas.
La respuesta corta, creo, es que cuando su base de datos necesita una aplicación para alcanzar un cierto nivel de complejidad, el costo de cumplir con sus requisitos es inferior al costo de la curva de aprendizaje de nhibernate. No puedo ofrecer respuestas completas, pero trataré de dar mi opinión sobre los elementos de la lista.
- Cuando está haciendo algo más que CRUD. La necesidad de consultas complejas en múltiples plataformas de bases de datos es probablemente un buen ejemplo. En este tipo de aplicaciones casi puedes terminar manteniendo dos bases de código separadas (bueno, realmente se desconectan si vas a la ruta de proceso almacenada) y puede haber valor para mantener todo tu código en .net (Es bueno poder unir prueba estas consultas con el resto de tu código, por ejemplo).
- Además de los problemas que se observan en los entornos de confianza media, no estoy seguro de qué pasa con la carga diferida que "simplemente no funciona" ahora. El único problema con la carga lenta en mis ojos es que debe ser consciente de ello para evitar algunos de los problemas que pueden surgir al obtener grandes cantidades de datos, principalmente el problema de selección N + 1.
- No necesita averiguar cómo crear extractos de lotes, solo necesita establecer un valor de configuración y olvidarse de ello.Esta es una optimización bastante grande que NHibernate hace por usted con un esfuerzo mínimo: su código puede ser mucho más limpio cuando solo está directamente relacionado con las operaciones y el control de las transacciones.
- El almacenamiento en memoria caché de los datos devueltos puede ser beneficioso cuando se procesan sus páginas de manera diferente para diferentes usuarios, o haciendo cualquier tipo de procesamiento no trivial en su capa de dominio. Incluso en escenarios básicos, con el almacenamiento en caché de salida de página podría terminar teniendo la página de edición, la página de detalles, etc. en su caché, mientras que el almacenamiento en caché de sus datos más cerca de la fuente solo necesita almacenar en caché la entidad una vez. El almacenamiento en caché más cerca de la fuente también le brinda más protección contra el servicio de datos obsoletos. Una memoria caché orientada a datos también se puede compartir en varias aplicaciones, ya sea a través de servicios o apuntando nHibernate a una tienda fuera de proceso como memcached o redis. Esto puede ser tremendamente valioso en algunos entornos.
- No estoy seguro de que necesite entender cómo funciona (muchas veces uso librerías de código abierto para protegerme de la necesidad de comprender los detalles de implementación de este tipo de cosas). Pero la respuesta corta es que ninguno de ellos se comporta de manera diferente en un escenario distribuido excepto en el almacenamiento en caché (y solo en el segundo nivel de almacenamiento en caché). Siempre que use un proveedor de caché distribuida (o apunte todos sus servidores al mismo proveedor de caché fuera de proceso) también debería ser bueno en ese frente.
Estoy hablando solo de nHibernate, pero imagino que para Hibernate la historia es muy parecida. Para aplicaciones de mayor escala y más complejas, puede haber un gran beneficio, pero hay una gran complejidad adicional que debe asumir para obtener este beneficio; aún así es probablemente menos complejo que implementar su propia solución para todos los problemas. * Hibernate resuelve para ti.
También tenía muchas preguntas sobre el almacenamiento en caché, parece. Sugiero leer más de this link para tener una idea de cómo funcionan las cachés de primer y segundo nivel. No voy a tratar de explicarlo aquí, porque parece que buscas una comprensión más profunda de la que puedo incluir en esta respuesta ya extensa :)