Anotação JPA de Dados de Primavera @Modifying
1. Introdução
Neste breve tutorial,we’ll learn how to create update queries with the Spring Data JPA @Query annotation. Faremos isso usando a anotação@Modifying.
Primeiro, vamos refrescar nossa memória e verhow to make queries using Spring Data JPA. Depois disso, vamos nos aprofundar no uso das anotações@Querye@Modifying. Finalmente, veremos como gerenciar o estado do nosso contexto de persistência ao usar consultas de modificação.
2. Consulta no JPA de Dados da Primavera
Primeiro, vamos recapitular3 mechanisms that Spring Data JPA provides for querying data in a database:
-
Métodos de consulta
-
anotação@Query
-
Implementação de repositório customizado
Vamos criar uma classeUser e um repositório Spring Data JPA correspondente para ilustrar esses mecanismos:
@Entity
@Table(name = "users", schema = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private LocalDate creationDate;
private LocalDate lastLoginDate;
private boolean active;
private String email;
}
public interface UserRepository extends JpaRepository {}
O mecanismo de métodos de consulta nos permite manipular os dados, derivando as consultas dos nomes dos métodos:
List findAllByName(String name);
void deleteAllByCreationDateAfter(LocalDate date);
Neste exemplo, podemos encontrar uma consulta que recupera usuários por seus nomes ou ainda uma consulta que remove usuários com uma data de criação após uma determinada data.
Quanto à anotação@Query,it provides us with the possibility to write a specific JPQL or SQL query in the @Query annotation:
@Query("select u from User u where u.email like '%@gmail.com'")
List findUsersWithGmailAddress();
Neste trecho de código, podemos ver uma consulta recuperando usuários com um endereço de e-mail@gmail.com.
O primeiro mecanismo nos permite recuperar ou excluir dados. Quanto ao segundo, ele nos permite executar praticamente qualquer consulta. No entanto,for updating queries, we must add the @Modifying annotation. Este será o tópico deste tutorial.
3. Usando a anotação@Modifying
O@Modifying annotation é usado para aprimorar a anotação@Query para executar não apenasSELECT consultas, mas tambémINSERT,UPDATE,DELETE e atéDDL consultas.
Vamos brincar um pouco com essa anotação e ver do que ela é feita.
Primeiro, vamos ver um exemplo de uma consulta UPDATE@Modifying:
@Modifying
@Query("update User u set u.active = false where u.lastLoginDate < :date")
void deactivateUsersNotLoggedInSince(@Param("date") LocalDate date);
Aqui, estamos desativando os usuários que não faziam login desde uma determinada data.
Vamos tentar outro em que excluiremos usuários desativados:
@Modifying
@Query("delete User u where u.active = false")
int deleteDeactivatedUsers();
Como podemos ver, esse método retorna um número inteiro. It’s a feature of Spring Data JPA @Modifying queries that provides us with the number of updated entities.
Devemos observar que a execução de uma consulta de exclusão com@Query funciona de maneira diferente dos métodos de consulta derivados de nomedeleteBy do Spring Data JPA. O último busca primeiro as entidades do banco de dados e as exclui uma a uma. Assim, isso significa que o método de ciclo de vida@PreRemove será chamado nessas entidades. No entanto, com o primeiro, uma única consulta é executada no banco de dados.
Finalmente, vamos adicionar uma colunadeleted à nossa tabelaUSERS com uma consultaDDL:
@Modifying
@Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true)
void addDeletedColumn();
Infelizmente, o uso de consultas modificadas deixa o contexto de persistência subjacente desatualizado. No entanto, é possível gerenciar essa situação. Esse é o assunto da próxima seção.
4. Gerenciando o contexto de persistência
If our modifying query changes entities contained in the persistence context, then this context becomes outdated. Uma maneira de gerenciar essa situação éclear the persistence context. Ao fazer isso, garantimos que o contexto de persistência buscará as entidades do banco de dados na próxima vez.
No entanto, não precisamos chamar explicitamente o métodoclear() noEntityManager. Podemos simplesmente usar oclearAutomatically property da anotação@Modifying:
@Modifying(clearAutomatically = true)
Dessa forma, garantimos que o contexto de persistência seja limpo após a execução de nossa consulta.
Mas, e se o nosso contexto de persistência contiver alterações não niveladas? Portanto, limpá-lo significaria eliminar as alterações não salvas. Felizmente, há outra propriedade da anotação que podemos usar -flushAutomatically:
@Modifying(flushAutomatically = true)
Agora, oEntityManager é liberado antes que nossa consulta seja executada.
5. Conclusão
Isso conclui este breve artigo sobre a anotação@Modifying. Vimos como usar essa anotação para executar consultas de atualização comoINSERT, UPDATE, DELETE,e atéDDL. Depois disso, aprendemos como gerenciar o estado do contexto de persistência com as propriedadesclearAutomaticallyeflushAutomatically.
Como de costume, o código completo deste artigo está disponívelover on GitHub.