Oi Tiago!
Na verdade são duas tecnologias distintas e complementares.
A JPA segue o conceito de ORM (Object-Relational Mapping) facilitando o código Java para acessar o banco de dados. Com ela, a gente utiliza anotações para mapear as classes (chamadas de entidades) do projeto que representam as tabelas no banco de dados. E, além disso, ela fornece a interface EntityManager
, que é utilizada para fazer o acesso ao banco de dados, para persistir uma entidade, buscar, excluir, etc.
Porém, para que a JPA funcione corretamente, é necessário que o banco de dados esteja devidamente configurado, com as tabelas criadas e de acordo com o mapeamento feito nas entidades. É justamente aí que entra um problema: como criar o banco de dados e as tabelas da aplicação nele?
Geralmente isso era feito de maneira manual, com você tendo que acessar o seu banco de dados (via terminal ou alguma aplicação gráfica) e nele executar os comandos SQL para criar as tabelas. O problema dessa abordagem é que você não guarda um histórico de evolução do banco de dados. Por exemplo, se no futuro for necessário desenvolver uma nova funcionalidade e ela precisar de uma nova tabela, provavelmente você acessaria o banco de dados novamente e executaria o comando SQL para criar a nova tabela.
Mas, e qual foi o comando exato utilizado para criar essa nova tabela? Esse comando ficou salvo em algum lugar? E se no futuro alguem precisar de todos os comandos executados no banco de dados até o momento? (ex: uma nova pessoa vai trabalhar no projeto e precisa criar o banco de dados da aplicação do zero no computador dela)
Aí é que entra uma ferramenta de Migration, como o Flyway ou Liquibase. Essas ferramentas não excluem a necessidade de se criar os scripts SQL para criação das tabelas no banco de dados. O que é elas fazem é padronizar como esses scripts serão armazenados e executados no banco de dados, mantendo com isso um histórico de evolução do banco de dados. É bem parecido com uma ferramenta de controle de versão, como o Git, onde registramos com commits cada versão do nosso código e depois conseguimos analisar o que cada commit modificou no projeto.
Assim, se uma pessoa nova precisar executar o projeto no computador dela, ou mesmo se você apagar todo o seu banco de dados e precisar criá-lo do zero, você não vai se preocupar em procurar quem tem ou quem sabe quais os scripts que precisam ser executados no banco e em qual ordem. Tudo será executado automaticamente quando você inicializar a aplicação. (Claro, considerando que a aplicação esteja utilizando essas ferramentas e que os scripts tenham sido criados corretamente).
Perceba então que são duas ferramentas distintas e complementares. Você pode utilizar JPA sem obrigatoriamente utilizar uma ferramenta de migration. Da mesma forma, pode utilizar uma ferramenta de migration mesmo sem utilizar a JPA.
Espero que tenha ficado mais claro o entendimento.
Bons estudos!