Spring-Data JPA & Modifying Queries

O Spring Framework possuí sub-projetos bem interessantes, entre eles, há o Spring-Data JPA. O Spring-Data JPA tem como foco a camada de persistencia em uma aplicação Java. Este projeto é baseado no padrão de projetos Repository e reduz muito a quantidade de código que deve ser escrito durante o desenvolvimento de uma aplicação.

Um dos pontos positivos do Spring-Data JPA é a possibilidade de herança de métodos pre-implementados como o save(), usado para inserir e alterar registros no banco de dados, e alguns métodos de consultas como findOne() e findAll(). Nas interfaces, as consultas podem ser realizadas por meio do uso de palavras chaves (Keywords) ou de instruções via JPQL por meio da anotação @Query.

Se você já trabalhou com o Spring-Data JPA, já deve saber que métodos não são implementados, ou seja, se cria a assinatura dos métodos na interface do tipo Repository e o Spring-Data fica com a responsabilidade da “implementação” destes métodos em tempo de execução.

Mas se os métodos não são implementados pelo desenvolvedor, e sim apenas a assinatura deles, como criar métodos de update ou delete, específicos para uma dada situação? Bem, para isso, o Spring-Data fornece a anotação @Modifying, a qual veremos como utilizar neste tutorial.

1. A anotação @Modifying

            A anotação @Modifying deve ser utilizada em conjunto com a anotação @Query. Na anotação @Query se adiciona a JPQL em questão, referente a operação de update ou delete, conforme a Listagem 1. E a anotação @Modifying será usada apenas para informar ao Spring-Data que a @Query não possuí um método de consulta, mas sim, um método de escrita.

Listagem 1. Interface UserRepository.
package com.mballem.tutorial.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import com.mballem.tutorial.entity.User;

public interface UserRepository extends JpaRepository<user, long=""> {
	
	@Modifying 
	@Transactional(readOnly = false)
	@Query("update User u set u.age = ?1 where u.id = ?2")
	int updateAge(Integer age, Long id); 
	
	@Modifying
	@Transactional(readOnly = false)
	@Query("delete from User u where u.fullName like ?1")
	int deleteByFullName(String fullName);
}

Na Listagem 1 você pode ver que a interface UserRepository tem dois métodos utilizando a anotação @Modifying. O primeiro método, updateAge(), tem como objetivo alterar a idade a partir de uma chave primaria. Veja que, os parametros informados são o novo valor para o campo age e o id para localizar a linha na tabela a ser modificada. Desta foram, a anotação @Query não foi utilizada para uma consulta, mas sim para uma operação de escrita. Já o método deleteByFullName() tem como objetivo, excluir uma linha no banco de dados a partir do parametro fullName.  

Tando as operação de update ou delete, são operações que poderiam ser realizadas a partir de métodos herdados da interface JpaRepository. Porém, a assinatura dos métodos herdados são muito especificas. Para trabalhar com o update, o único parametro aceito é o objeto da entidade envolvida na operação. E para usar o delete, os parametros são ou o objeto da entidade ou o identificodor deste objeto. Então, caso queira alterar estes parametros, como no método deleteByFullName(), a saída é usar @Modifying e @Query com sua instrução de delete. E é claro, se quiser uma operação de delete ou update diferente das já fornecidas pelo Spring-Data, vai precisar usar então a @Modifying.

Outro ponto importante que deve ser levado em conta é o uso da anotação @Transactional com o atributo readOnly setado como false. Isto porque, todas as interfaces que herdam JpaRepository são por padrão do tipo readOnly = true, ou seja, todos os métodos que você assinar na interface, serão do tipo leitura e não de escrita. Então, para evitar uma exceção na transação dos métodos anotados com @Modifying, é preciso inserir a @Transactional(readOnly = false), para dizer que esta transação não será para leitura e sim de escrita.

Referencias:

Documentação Modifying Queries – http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#jpa.modifying-queries

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...