Anotación Modifying en Spring Data

Modifying en Spring Data

Modifying en Spring Data


En este nuevo artículo vamos a ver cómo podemos realizar actualizaciones en nuestra base de Datos haciendo uso de la anotación Modifying en Spring Data.

Cuando utilizamos el @Query en nuestras queries para realizar actualizaciones en nuestra Base de Datos necesitamos hacer uso de @Modifying.

Modificaciones en Base de Datos con Spring Data

Existen diferentes aproximaciones para realizar modificaciones en nuestra Base de Datos con Spring Data:

  • Query proporcionadas a través de la interfaz CrudRepository o JPARepository.
  • Haciendo uso de @Query creando los update manualmente, con JPQL o SQL.

En este artículo vamos a ver la aproximación del uso de @Modifying para realizar modificaciones en nuestra Base de Datos con @Query en Spring Data.

Por ejemplo para realizar inserts, creates o deletes:

@Modifying
@Query(value = "insert into Car (id,brand,color) "
        + "VALUES(:id,:brand,:color)", nativeQuery = true)
public void insertCar(@Param("id") int id, @Param("brand") String brand,
        @Param("color") String color);
@Modifying
@Query("update Car c SET c.color = :color WHERE s.id = :id")
public void updateColor(@Param("color") String color, @Param("id") int id)

Uso de @Modifying en Spring Data

El uso de @Modifying es imprescindible para todas aquellas queries que van a modificar nuestra Base de Datos y sean con @Query, no hay problema para usarla también sobre select.

Por ejemplo en lugar de usar el deleteBy de JPA vamos crear una query propia para eliminar un Car by Id:

@Modifying
@Query("delete Car c where c.id = :id")
int deleteCarById(@Param("id") int id);

El delete anterior nos va a eliminar un objeto Car de Base de Datos por id, siendo esta forma algo más óptima en temas de rendimiento que hacer uso de deleteBy. Cuando eliminamos un único objeto por su id, el rendimiento será similar, pero si eliminamos una colección de objetos, será mucho peor el rendimiento, por ejemplo vamos a ver la siguiente query:

@Modifying
@Query("delete Car c where c.color = :color")
int deleteCarsByColor(@Param("color") String color);

En la query anterior, vamos a eliminar todos los coches con un color en concreto. Si empleamos la query anterior se eliminarán con una única query, en cambio si usamos el deleteBy vamos primero a recuperar y luego a eliminar.

Uso de Persitence Context con anotación Modifying en Spring Data

Cuando hacemos uso de la anotación de Spring @Modifying va a provocar dejar obsoleto el contexto de persistencia o que nuestro contexto tengan cambios que no se han persistido.

Para solucionar estos problemas, Spring Data nos proporciona dos propiedades para solventar los problemas del Persistence Context con @Modifying:

  • clearAutomatically: Va a permitir limpiar el contexto para asegurar que las entidades de Base de Datos son correctas.
  • flushAutomatically: Hace flush sobre las entidades para actualizar el contexto.

Para limpiar el contexto sería de la siguiente forma:

@Modifying(clearAutomatically = true)

Para hacer flush utilizaríamos la siguiente aproximación:

@Modifying(flushAutomatically = true)

Errores al modificar nuestra Base de Datos con Spring Data

Cuando creamos una query en la que no aplicamos la anotación Modifying nuestra aplicación va a lanzar una excepción. Por ejemplo si utilizamos la query que hace delete sin hacer uso de @Modifying:

@Query("delete Car c where c.color = :color")
int deleteCarsByColor(@Param("color") String color);

obtendremos la siguiente excepción:

Caused by: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations [delete com.refactorizando.modifying.example.entity.Car c where c.color = :color]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.errorIfDML(QueryTranslatorImpl.java:314)
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:365)
	at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:220)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1508)
	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1537)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1505)
	... 117 more

Conclusión

La anotación Modifying en Spring Data es imprescindible usarla cuando creamos cualquier query en Spring que modifican la Base de Datos. En función de la modificación que realicemos en Base de Datos será mejor realizar queries escritas que las que nos proporciona directamente JPA, como por ejemplo los borrados.

Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *