3.0 / 5
La persistencia de datos es crucial en la mayoría de las aplicaciones. Aunque no es obligatorio que una aplicación mantenga sus datos persistidos, es una práctica común en aplicaciones grandes de diversos campos, desde videojuegos hasta plataformas de redes sociales o sitios web de blogs.
En Java, el proceso de persistencia ha recibido mucha atención a lo largo del tiempo, mostrando una evolución visible. Comenzando con el trabajo directo con la API JDBC y terminando con un mecanismo estandarizado que se vuelve cada vez más abstracto y fácil de usar para los desarrolladores.
Durante esta evolución, se crearon muchas tecnologías de persistencia y la diferencia entre ellas puede a menudo crear confusión entre los desarrolladores. Estas tecnologías son Hibernate, JPA y Spring Data JPA.
¿Deberíamos elegir una de ellas al desarrollar o podemos usarlas todas al mismo tiempo?
Vamos a analizarlas una por una.
Hibernate es uno de los frameworks ORM (Object Relational Mapping) más populares en Java y se utiliza para una mejor gestión de la interacción entre una aplicación Java y la base de datos. Puede mapear bidireccionalmente las clases Java a las tablas de la base de datos, proporcionando una solución completa para el desajuste Objeto/Relacional.
Hibernate utiliza anotaciones para crear metadatos sobre los cuales se realiza el mapeo. Algunas de las anotaciones más utilizadas se muestran a continuación.
@Entity
@Table(name = "CAR")
public class Car {
@Id
@Column(name = "CAR_ID")
private Long carId;
@Column(name = "COLOR")
private String color;
@ManyToOne()
@JoinColumn(name = "OWNER_ID")
private Owner owner;
}
Code language: Java (java)
Una de las partes centrales de Hibernate es su interfaz Session
. Las sesiones son creadas y gestionadas por un SessionFactory
. La sesión permite construir consultas, realizar operaciones CRUD y gestionar transacciones. Los métodos más importantes de Session
son:
/*
* Guarda un nuevo objeto en la base de datos.
*/
Object save(Object var1);
/*
* Actualiza un objeto en la base de datos.
*/
void update(Object var1);
/*
* Elimina un objeto de la base de datos.
*/
void delete(Object var1);
/*
* Obtiene un objeto de la base de datos.
*/
<T> T get(Class<T> var1, Object var2);
/*
* Crea una nueva consulta SQL para ser ejecutada.
*/
Query createQuery(String var1);
/*
* Inicia una nueva transacción de base de datos.
*/
Transaction beginTransaction();
Code language: Java (java)
Hibernate utiliza la API JDBC para comunicarse con la base de datos. Abstrae muchas de las complejidades de la API JDBC, permitiendo a los desarrolladores trabajar directamente con objetos Java mientras realiza todos los procesos necesarios de conexión a la base de datos de manera interna.
Las entidades Java utilizan anotaciones de Hibernate, que las convierte en SQL y las envía a la API JDBC para ser ejecutadas. El proceso es bidireccional. Algunas de las principales ventajas de Hibernate son:
Con el tiempo, Hibernate se adhirió al estándar JPA e implementó sus métodos. Su implementación nativa también se mantuvo, tanto para hacerla compatible hacia atrás como para seguir utilizando algunas de sus características personalizadas. Pero, ¿qué es esa JPA de la que estamos hablando?
JPA (Java Persistence API) es una especificación, un conjunto de reglas que debe implementar cualquier framework ORM que quiera ser parte de un mecanismo estandarizado de persistencia de datos en Java.
JPA no es un framework como Hibernate, es solo una interfaz que debe ser implementada por un framework ORM.
Uno de los principales propósitos de JPA es crear un enfoque estándar para la persistencia de datos en Java, mejorando la interoperabilidad entre los frameworks ORM que la implementan. Imaginemos una aplicación que utiliza Hibernate como framework ORM y, en algún momento, Hibernate debe ser reemplazado por otra herramienta ORM, como Eclipse Link. Si ambos se adhieren al estándar JPA, sería más fácil realizar la transición de uno a otro. Vale la pena mencionar que, incluso si es más fácil hacer la transición, algunas implementaciones nativas de uno de los frameworks pueden no estar presentes en el otro (como ocurre con Hibernate).
JPA se basa en EntityManager
y EntityManagerFactory
para gestionar el proceso de persistencia (Esto es similar a la Session
de Hibernate. De hecho, desde que Hibernate se adhirió a JPA, Session
extiende EntityManager
). El EntityManager
funciona como un Contexto de Persistencia que gestiona los cambios de estado de las entidades y las transforma en consultas SQL. Los métodos principales de EntityManager
son:
/*
* Devuelve una entidad por su clave primaria.
*/
public <T> T find(Class<T> entityClass, Object primaryKey);
/*
* Crea una nueva entidad transitoria que será insertada en la base de datos durante
* el próximo flush().
*/
public void persist(Object entity);
/*
* Transforma una entidad separada (una entidad que fue gestionada por un Contexto de Persistencia en algún momento) en una entidad transitoria.
*/
public <T> T merge(T entity);
/*
* Elimina la entidad de la base de datos en la próxima operación flush().
*/
public void remove(Object entity);
/*
* Sincroniza el Contexto de Persistencia con la base de datos subyacente.
*/
public void flush();
Code language: Java (java)
Las transiciones de estado de las entidades y cómo son gestionadas por el Contexto de Persistencia son realmente importantes para entender cómo funciona el EntityManager
, pero es un tema ligeramente diferente que no se cubrirá en este artículo.
JPA también introduce un nuevo lenguaje, el Lenguaje de Consulta de Persistencia de Java (JPQL). Crea la posibilidad de construir consultas SQL sin la necesidad de escribir consultas en forma de cadenas, reduciendo aún más la necesidad de trabajar con SQL plano y haciendo la experiencia de codificación más intuitiva para los desarrolladores Java.
Las principales ventajas de JPA son:
Ahora que la relación entre Hibernate y JPA está clara, podemos avanzar a Spring Data JPA.
Si Hibernate y JPA pueden ser utilizados en cualquier aplicación Java, Spring Data JPA debe ser parte de una aplicación Spring. Spring Data JPA es parte del proyecto Spring Data y su objetivo es reducir la complejidad de trabajar con la base de datos en una aplicación Spring al reducir el código boilerplate necesario para crear repositorios. Añade un nivel extra de abstracción, haciendo el trabajo con JPA más productivo.
En el núcleo de Spring Data JPA se encuentra JpaRepository
, una interfaz extremadamente útil para los desarrolladores, que viene con capacidades listas para usar como operaciones CRUD, clasificación y paginación. JpaRepository
tiene dos parámetros genéricos: una clase de entidad y su tipo de clave primaria. Extiende otros repositorios útiles como ListCrudRepository
y ListPagingAndSortingRepository
. Finalmente, todas las interfaces de repositorio extienden la interfaz Repository
que no tiene métodos y se utiliza solo como un marcador para las interfaces de repositorio.
Jerarquía de Jpa Repository
Una de las mayores ventajas de Spring Data JPA es que, utilizando las capacidades de Spring, la implementación de los repositorios se realiza automáticamente en tiempo de ejecución con la ayuda de SimpleJpaRepository
. Cuando un desarrollador desea crear un nuevo repositorio para acceder a los datos persistidos, solo necesita crear una interfaz que extienda JpaRepository
y todos sus métodos serán implementados automáticamente. ¡Eso es genial!
Para responder a la pregunta que se planteó al principio del artículo:
SÍ, Hibernate, JPA y Spring Data JPA pueden usarse juntos, a pesar de sus similitudes, ya que cada uno de ellos tiene un propósito diferente en la fase de desarrollo.
Fuente aquí.