Me pregunto si puedo cambiar de Java a Scala en un proyecto Spring + Hibernate para aprovechar algunas características de Scala, como la coincidencia de patrones, la Opción y lo que me parece una sintaxis más limpia en general. He estado buscando el ORM por defecto en el ecosistema Scala y he encontrado que piensa como Activar (pero principalmente trato de encontrar si Hibernate se puede usar con Scala). Buscando esto, lo he leído en la documentación de Play sobre JPA + Scala.
Pero el punto más importante es: ¿realmente necesita un mapeador Relacional a Objetos cuando tiene el poder de un lenguaje funcional? Probablemente no. JPA es una forma conveniente de abstraer la falta de poder de Java en la transformación de datos, pero realmente se siente mal cuando comienza a usarlo desde Scala.
No tengo una comprensión profunda de cómo usar la programación funcional para crear una aplicación completa (es por eso que tengo la intención de usar Scala para poder entender esto gradualmente, ya que combina OO + Funcional), por lo que no puedo entender por qué no necesitaría un ORM con un lenguaje funcional y cuál sería el enfoque funcional para abordar la persistencia del modelo de dominio.
Un enfoque DDD para la lógica empresarial todavía tiene sentido con Scala, ¿no?
fuente
Respuestas:
Bueno, una cosa que es importante hacer cuando tenemos una discusión como esta es distinguir claramente entre mapeadores relacionales de objetos ("ORM") y las capas de abstracción de la base de datos . Un ORM es un tipo de capa de abstracción de base de datos, pero no todas las capas de abstracción de base de datos son ORM. Una buena herramienta para estudiar para comprender esto es la popular biblioteca SQLAlchemy de Python , que se autodenomina como un "kit de herramientas SQL y Object Relational Mapper" (mi negrita), con la idea de que estas son cosas diferentes. Como lo pusieron en su página de características clave :
La primera página describe el ORM de esta manera:
La idea clave de un ORM es tratar de salvar el famoso desajuste de impedancia relacional de objetos . Esto significa definir las relaciones entre las clases definidas por el usuario con las tablas en un esquema de base de datos y proporcionar operaciones automáticas de "guardar" y "cargar" para las clases de su aplicación.
En contraste, las capas de abstracción de bases de datos que no son ORM tienden a estar más comprometidas con el modelo de datos relacionales y con SQL, y no con la orientación a objetos. Entonces, en lugar de presentar "asignaciones" entre tablas y clases y ocultar el esquema de la base de datos del programador, tienden a exponer la base de datos al programador pero con mejores API y abstracciones. Por ejemplo, los constructores de consultas SQL le permiten generar consultas SQL complejas mediante programación, sin manipulación de cadenas, como este ( un ejemplo de la biblioteca jOOQ para Java ):
Ahora, el marco de Play no parece estar 100% en línea con lo que acabo de describir , pero su argumento parece estar en este espacio general: trabaje con el modelo relacional directamente en lugar de traducirlo a clases y viceversa.
La biblioteca jOOQ es digno de estudio como contrapunto a ORM. También tienen algunas entradas de blog relevantes que vale la pena leer:
fuente
Es un poco difícil de explicar hasta que hayas realizado mucha programación funcional. En la programación orientada a objetos, sus datos están atascados en un objeto y permanecen allí. Ese objeto se pasa un poco y se modifica bastante, pero generalmente se trabaja fundamentalmente con la misma "identidad" durante la vida útil de esos datos.
Los ORM generalmente están diseñados en torno a ese paradigma. Recupera algunos datos de la base de datos, los transforma en un objeto, posiblemente los modifica un montón, y cuando haya terminado, todavía tiene el mismo objeto que puede volver a escribir en la base de datos.
La programación funcional funciona de manera diferente. Sus datos no mantienen una identidad única durante su vida útil. Se divide, copia, comparte y transforma. De alguna manera fluye a través de un montón de funciones, luego eventualmente se vuelve a ensamblar en el formulario de salida que necesita. Para que cualquier API de base de datos se sienta natural en un lenguaje funcional, tiene que tener eso en cuenta, y JPA no.
fuente
En scala todavía es útil mapear tablas de bases de datos a objetos, y hay varias formas de hacerlo.
Un marco popular en el mundo de Scala es elegante . No es un ORM, porque hace menos (es decir, no busca relaciones sin que se le diga que haga uniones explícitamente).
Por lo tanto, todavía asigna objetos a las filas de la base de datos, pero sus objetos son inmutables (por lo tanto, no se elimina el estado) y ejecuta consultas explícitamente utilizando un DSL monádico. El resultado es que obtienes muchas de las partes "buenas" de un ORM sin los problemas relacionados con la mutabilidad y los problemas impredecibles de N + 1.
Se debe tener en cuenta que las personas han tenido un gran éxito al usar bibliotecas mucho más delgadas, como anorm o JDBC directo, también, utilizando técnicas funcionales para mantener el código hermoso.
Una biblioteca fantástica que aplica técnicas funcionales sobre JDBC también es doobie .
Por lo tanto, tiene muchas opciones para acceder a la base de datos, pero Hibernate (que parece ser el ORM de facto) no es una de las mejores, debido a que está sesgado hacia la mutabilidad.
fuente
No necesita un ORM incluso en lenguajes orientados a objetos.
Primero, ¿quién dijo que sus datos deberían copiarse físicamente de su almacenamiento persistente a su objeto? Alan Kay , un hombre detrás de Smalltalk, quería objetos para deshacerse de los datos . Sugirió que un objeto solo puede tener una referencia a alguna área donde se almacenan sus datos.
Segundo, ¿cuál es la mejor manera de lograrlo? Recomiendo identificar sus objetos por sus responsabilidades , y no pensar en los datos que poseen. Si has oído hablar del enfoque de las tarjetas CRC, se usa exactamente para eso.
Y, finalmente, en caso de que alguna vez regrese al campo OO, aquí hay una forma de implementarlo .
fuente