Arquitetura em MVC com Spring Boot: Uma Abordagem Detalhada para Desenvolvimento de Software
O padrão de arquitetura Model-View-Controller (MVC) se consolidou como uma escolha popular para o desenvolvimento de interfaces de usuário (UIs) em aplicações web modernas. Em conjunto com o Spring Boot, um framework leve e poderoso para Java, o MVC oferece uma base sólida para a construção de aplicações escaláveis, maintainable e robustas. Este artigo acadêmico apresenta uma análise aprofundada da arquitetura MVC com Spring Boot, explorando seus fundamentos conceituais, implementação prática e benefícios na engenharia de software moderna.
Keywords: #MVCArchitecture, #SpringBoot, #SoftwareDevelopment, #ModernSoftwareEngineering, #WebUIs #JAVA.
O desenvolvimento de software moderno exige soluções flexíveis, escaláveis e maintainable que atendam às demandas crescentes de aplicações web complexas. Nesse contexto, a arquitetura MVC surge como um padrão consagrado para a construção de interfaces de usuário (UIs) intuitivas e responsivas. Combinado com o Spring Boot, um framework Java leve e de alto desempenho, o MVC oferece um conjunto poderoso de ferramentas para o desenvolvimento de aplicações web modernas.
A escolha de uma arquitetura adequada para o desenvolvimento de software é crucial para garantir a qualidade, a escalabilidade e a maintainability da aplicação. O padrão MVC, com sua separação clara de responsabilidades entre os componentes Model, View e Controller, apresenta diversas vantagens que o tornam uma opção atraente para o desenvolvimento web moderno.
Este artigo acadêmico tem como objetivo principal fornecer uma análise detalhada da arquitetura MVC com Spring Boot, explorando seus fundamentos conceituais, implementação prática e benefícios na engenharia de software moderna. Através de uma abordagem abrangente e fundamentada em pesquisas relevantes, o artigo visa contribuir para a compreensão aprofundada desse padrão de arquitetura e sua aplicação eficaz no desenvolvimento de aplicações web robustas e escaláveis.
Fundamentos da Arquitetura MVC
A arquitetura MVC, sigla para Model-View-Controller, é um padrão de design que propõe a separação de responsabilidades em três componentes principais:
- Model (Modelo): Representa os dados da aplicação e a lógica de negócio subjacente. O Model é responsável por armazenar, manipular e recuperar dados, encapsulando a lógica de negócio da aplicação.
- View (Visão): É responsável pela apresentação dos dados do Model para o usuário. A View gera a interface gráfica da aplicação, exibindo os dados de forma visual e interativa para o usuário.
- Controller (Controlador): Serve como intermediário entre o Model e a View, gerenciando as interações entre os dois componentes. O Controller recebe requisições do usuário, manipula os dados do Model e atualiza a View de acordo com as alterações.
Benefícios da Arquitetura MVC
A adoção da arquitetura MVC oferece diversos benefícios para o desenvolvimento de software:
- Separação de Responsabilidades: A clara divisão de responsabilidades entre os componentes Model, View e Controller facilita o desenvolvimento, a testabilidade e a manutenção da aplicação.
- Reusabilidade de Componentes: Os componentes do MVC podem ser reutilizados em diferentes partes da aplicação ou em outros projetos, promovendo código modular e eficiente.
- Maior Testabilidade: A separação de responsabilidades facilita a criação de testes unitários para Controllers, testes de integração para verificação da interação entre camadas e testes de UI para garantir o comportamento correto da interface do usuário.
- Flexibilidade e Escalabilidade: A arquitetura MVC se adapta facilmente a mudanças nos requisitos da aplicação, permitindo a adição de novas funcionalidades e o dimensionamento da aplicação para atender a demandas crescentes.
3. Implementação da Arquitetura MVC com Spring Boot
O Spring Boot oferece um conjunto abrangente de ferramentas para a implementação da arquitetura MVC em aplicações Java. Através de anotações e recursos específicos, o Spring Boot simplifica o desenvolvimento e a configuração das camadas Model, View e Controller.
3.1 Camada Model
A camada Model representa os dados da aplicação e a lógica de negócio. No Spring Boot, os objetos Model podem ser anotados com @Entity para serem mapeados para entidades JPA (Java Persistence API), facilitando o acesso e a manipulação de dados em bancos de dados relacionais.
3.2 Camada View
A camada View é responsável pela apresentação dos dados do Model para o usuário. No Spring Boot, diversas tecnologias podem ser utilizadas para construir as Views, como Thymeleaf, JSP (JavaServer Pages) ou frameworks JavaScript como React ou Angular. O Spring Boot oferece suporte nativo para Thymeleaf, um motor de templates HTML poderoso e flexível. Thymeleaf permite aos desenvolvedores criar templates HTML dinâmicos que podem ser preenchidos com dados do Model.
3.3 Camada Controller
A camada Controller serve como intermediário entre o Model e a View, gerenciando as interações entre os dois componentes. No Spring Boot, os Controllers são implementados como classes Java anotadas com @Controller. As anotações @GetMapping, @PostMapping, @PutMapping e @DeleteMapping são utilizadas para mapear requisições HTTP para métodos específicos do Controller.
3.4 Exemplo de Implementação Completo
Para ilustrar de forma mais abrangente a implementação da arquitetura MVC com Spring Boot, consideremos o desenvolvimento de uma aplicação web simples para gerenciamento de tarefas. A aplicação permite aos usuários:
- Cadastrar novas tarefas;
- Listar todas as tarefas;
- Visualizar os detalhes de uma tarefa específica;
- Editar uma tarefa existente;
- Excluir uma tarefa.
3.4.1 Camada Model
A camada Model define as entidades que representam os dados da aplicação. Neste exemplo, utilizaremos duas entidades:
- Tarefa: Representa uma tarefa a ser gerenciada. Possui atributos como id, titulo, descricao, dataCriacao e status.
@Entity
public class Tarefa {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String titulo;
private String descricao;
@Temporal(TemporalType.DATE)
private Date dataCriacao;
@Enumerated(EnumType.STRING)
private StatusTarefa status;
// Getters, setters e construtores omitidos por brevidade
}
- StatusTarefa: Define os diferentes estados em que uma tarefa pode se encontrar (pendente, em andamento, concluída).
public enum StatusTarefa {
PENDENTE,
EM_ANDAMENTO,
CONCLUIDA
}
3.4.2 Camada View
A camada View é responsável pela apresentação dos dados do Model para o usuário. Neste exemplo, utilizaremos Thymeleaf para criar templates HTML dinâmicos.
3.4.2.1 Listagem de Tarefas (index.html)
O template index.html exibe a lista de todas as tarefas cadastradas no sistema.
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Gerenciamento de Tarefas</title>
</head>
<body>
<h1>Lista de Tarefas</h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Título</th>
<th>Descrição</th>
<th>Data Criação</th>
<th>Status</th>
<th>Ações</th>
</tr>
</thead>
<tbody>
<tr>
<td>${tarefa.id}</td>
<td>${tarefa.titulo}</td>
<td>${tarefa.descricao}</td>
<td>${tarefa.dataCriacao}</td>
<td>${tarefa.status}</td>
<td>
<a href="/tarefas/${tarefa.id}">Detalhes</a>
<a href="/tarefas/${tarefa.id}/editar">Editar</a>
<a href="/tarefas/${tarefa.id}/excluir">Excluir</a>
</td>
</tr>
</tbody>
</table>
<a href="/tarefas/nova">Nova Tarefa</a>
</body>
</html>
3.4.2.2 Cadastro de Nova Tarefa (nova.html)
O template nova.html permite ao usuário cadastrar uma nova tarefa.
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Nova Tarefa</title>
</head>
<body>
<h1>Cadastro de Nova Tarefa</h1>
<form method="post" action="/tarefas">
<label for="titulo">Título:</label>
<input type="text" id="titulo" name="titulo" required>
<label for="descricao">Descrição:</label>
<textarea id="descricao" name="descricao" required></textarea>
<label for="status">Status:</label>
<select id="status" name="status" required>
<option value="PENDENTE">Pendente</option>
<option value="EM_ANDAMENTO">Em Andamento</option>
<option value="CONCLUIDA">Concluída</option>
</select>
<button type="submit">Salvar</button>
</form>
</body>
</html>
3.4.2.3 Detalhes de Tarefa (detalhes.html)
O template detalhes.html exibe os detalhes de uma tarefa específica.
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Detalhes da Tarefa</title>
</head>
<body>
<h1>Detalhes da Tarefa</h1>
<p><strong>ID:</strong> ${tarefa.id}</p>
<p><strong>Título:</strong> ${tarefa.titulo}</p>
<p><strong>Descrição:</strong> ${tarefa.descricao}</p>
<p><strong>Data Criação:</strong> ${tarefa.dataCriacao}</p>
<p><strong>Status:</strong> ${tarefa.status}</p>
<a href="/tarefas/${tarefa.id}/editar">Editar</a>
<a href="/tarefas/${tarefa.id}/excluir">Excluir</a>
</body>
</html>
3.4.2.4 Edição de Tarefa (editar.html)
O template editar.html permite ao usuário editar os dados de uma tarefa.
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Editar Tarefa</title>
</head>
<body>
<h1>Editar Tarefa</h1>
<form method="post" action="/tarefas/${tarefa.id}">
<input type="hidden" name="id" value="${tarefa.id}">
<label for="titulo">Título:</label>
<input type="text" id="titulo" name="titulo" value="${tarefa.titulo}" required>
<label for="descricao">Descrição:</label>
<textarea id="descricao" name="descricao" required>${tarefa.descricao}</textarea>
<label for="status">Status:</label>
<select id="status" name="status" required>
<option value="PENDENTE" ${tarefa.status.name() == 'PENDENTE' ? 'selected' : ''}>Pendente</option>
<option value="EM_ANDAMENTO" ${tarefa.status.name() == 'EM_ANDAMENTO' ? 'selected' : ''}>Em Andamento</option>
<option value="CONCLUIDA" ${tarefa.status.name() == 'CONCLUIDA' ? 'selected' : ''}>Concluída</option>
</select>
<button type="submit">Salvar</button>
</form>
</body>
</html>
3.4.3 Camada Controller
A camada Controller define os endpoints HTTP da aplicação e manipula as requisições do usuário.
@RestController
@RequestMapping("/tarefas")
public class TarefaController {
@Autowired
private TarefaService tarefaService;
@GetMapping
public List<Tarefa> listarTodasTarefas() {
return tarefaService.listarTodasTarefas();
}
@GetMapping("/{id}")
public Tarefa buscarTarefaPorId(@PathVariable Long id) {
return tarefaService.buscarTarefaPorId(id);
}
@PostMapping
public ResponseEntity<Tarefa> salvarTarefa(@RequestBody Tarefa tarefa) {
Tarefa tarefaSalva = tarefaService.salvarTarefa(tarefa);
return ResponseEntity.ok(tarefaSalva);
}
@PutMapping("/{id}")
public ResponseEntity<Tarefa> editarTarefa(@PathVariable Long id, @RequestBody Tarefa tarefa) {
tarefa.setId(id);
Tarefa tarefaAtualizada = tarefaService.editarTarefa(tarefa);
return ResponseEntity.ok(tarefaAtualizada);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> excluirTarefa(@PathVariable Long id) {
tarefaService.excluirTarefa(id);
return ResponseEntity.noContent().build();
}
}
3.4.4 Camada Service
A camada Service encapsula a lógica de negócio da aplicação, realizando operações sobre os dados do Model.
@Service
public class TarefaService {
@Autowired
private TarefaRepository tarefaRepository;
public List<Tarefa> listarTodasTarefas() {
return tarefaRepository.findAll();
}
public Tarefa buscarTarefaPorId(Long id) {
return tarefaRepository.findById(id).orElseThrow(() -> new TarefaNotFoundException(id));
}
public Tarefa salvarTarefa(Tarefa tarefa) {
return tarefaRepository.save(tarefa);
}
public Tarefa editarTarefa(Tarefa tarefa) {
return tarefaRepository.save(tarefa);
}
public void excluirTarefa(Long id) {
tarefaRepository.deleteById(id);
}
}
3.4.5 Repositório
O repositório define os métodos de acesso aos dados da aplicação, utilizando a tecnologia JPA para interagir com o banco de dados.
@Repository
public interface TarefaRepository extends JpaRepository<Tarefa, Long> {
}
3.4.6 Exceções Personalizadas
Exceções personalizadas podem ser criadas para tratar de erros específicos da aplicação.
@ResponseStatus(HttpStatus.NOT_FOUND)
public class TarefaNotFoundException extends RuntimeException {
public TarefaNotFoundException(Long id) {
super("Tarefa não encontrada com o ID: " + id);
}
}
3.4.7 Teste Unitário (TarefaController)
O teste unitário verifica o comportamento do Controller ao listar todas as tarefas.
@SpringBootTest
public class TarefaControllerTests {
@Autowired
private MockMvc mockMvc;
@Autowired
private TarefaService tarefaService;
@Test
public void listarTodasTarefas_deveRetornarListaDeTarefas() throws Exception {
// Cria duas tarefas de teste
Tarefa tarefa1 = new Tarefa("Tarefa 1", "Descrição 1", StatusTarefa.PENDENTE);
Tarefa tarefa2 = new Tarefa("Tarefa 2", "Descrição 2", StatusTarefa.EM_ANDAMENTO);
// Salva as tarefas no banco de dados
tarefaService.salvarTarefa(tarefa1);
tarefaService.salvarTarefa(tarefa2);
// Realiza a requisição GET para listar todas as tarefas
mockMvc.perform(get("/tarefas"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.[]").isArray())
.andExpect(jsonPath("$.[0].titulo").value("Tarefa 1"))
.andExpect(jsonPath("$.[1].titulo").value("Tarefa 2"));
}
}
3.4.8 Teste de Integração (TarefaService)
O teste de integração verifica o comportamento do Service ao salvar uma nova tarefa.
@SpringBootTest
public class TarefaServiceTests {
@Autowired
private TarefaService tarefaService;
@Autowired
private TarefaRepository tarefaRepository;
@Test
public void salvarTarefa_deveSalvarNovaTarefaNoBancoDeDados() {
// Cria uma nova tarefa
Tarefa tarefa = new Tarefa("Nova Tarefa", "Descrição da Nova Tarefa", StatusTarefa.PENDENTE);
// Salva a tarefa
tarefaService.salvarTarefa(tarefa);
// Busca a tarefa salva no banco de dados
Tarefa tarefaSalva = tarefaRepository.findByTitulo("Nova Tarefa");
// Verifica se a tarefa foi salva corretamente
assertThat(tarefaSalva).isNotNull();
assertThat(tarefaSalva.getTitulo()).isEqualTo("Nova Tarefa");
assertThat(tarefaSalva.getDescricao()).isEqualTo("Descrição da Nova Tarefa");
assertThat(tarefaSalva.getStatus()).isEqualTo(StatusTarefa.PENDENTE);
}
}
3.4.9 Observações Importantes
- O exemplo apresentado é simplificado e pode ser expandido para incluir funcionalidades adicionais, como validação de dados, autenticação e autorização, tratamento de erros mais abrangente, testes de ponta a ponta e implementação de boas práticas de desenvolvimento.
- A utilização de ferramentas como Spring Boot DevTools, Lombok e MapStruct pode facilitar o desenvolvimento e reduzir o código repetitivo.
- A adoção de práticas de design de software como SOLID, DDD e Clean Architecture pode aprimorar a qualidade, a maintainability e a testabilidade da aplicação.
- A documentação clara e concisa do código, tanto no nível de classes quanto no nível de comentários, é crucial para facilitar a compreensão e a manutenção da aplicação.
- A realização de revisões de código regulares por outros desenvolvedores pode identificar erros, problemas de design e oportunidades de melhoria no código.
- A utilização de ferramentas de versionamento de código como Git e de ferramentas de integração contínua (CI/CD) pode garantir a consistência do código, automatizar testes e facilitar a implantação da aplicação em ambientes de produção.
- A adoção de boas práticas de segurança, como autenticação, autorização e criptografia de dados, é fundamental para proteger a aplicação contra acessos não autorizados e vulnerabilidades.
- A realização de testes de segurança regulares pode identificar e corrigir vulnerabilidades na aplicação antes que sejam exploradas por invasores.
- A monitoramento da aplicação em produção é essencial para identificar gargalos de performance, erros e outros problemas que possam afetar a experiência do usuário.
Benefícios da Arquitetura MVC com Spring Boot na Engenharia de Software
A adoção da arquitetura MVC com Spring Boot oferece diversos benefícios para a engenharia de software moderna:
- Desenvolvimento Ágil: O Spring Boot simplifica a configuração e o desenvolvimento, permitindo aos desenvolvedores focarem na lógica de negócio e na implementação rápida de funcionalidades.
- Testabilidade Aprimorada: A separação de responsabilidades facilita a criação de testes unitários para Controllers, testes de integração para verificação da interação entre camadas e testes de UI para garantir o comportamento correto da interface do usuário.
- Manutenção Simplificada: A arquitetura modular facilita a identificação e correção de erros, bem como a adição de novas funcionalidades sem afetar outras partes da aplicação.
- Escalabilidade e Performance: O Spring Boot oferece recursos para construir aplicações altamente performáticas e escaláveis, permitindo lidar com grandes volumes de usuários e transações.
Estudo de Caso: Aplicação Web Simples com Spring Boot e MVC
Para ilustrar a implementação da arquitetura MVC com Spring Boot, podemos considerar o desenvolvimento de uma aplicação web simples para gerenciamento de tarefas. A aplicação permite aos usuários cadastrar, listar, editar e excluir tarefas.
- Model: A camada Model pode conter entidades JPA para representar tarefas (incluindo atributos como título, descrição, data de criação e status).
- View: A camada View pode utilizar templates Thymeleaf para exibir listas de tarefas, formulários para cadastro e edição, e detalhes específicos de cada tarefa.
- Controller: A camada Controller processa requisições do usuário, como requisições GET para listar tarefas, POST para criar novas tarefas, e PUT/DELETE para editar ou excluir tarefas. O Controller interage com o serviço de tarefas para manipular os dados do Model.
- Serviço de Tarefas: O serviço de tarefas encapsula a lógica de negócio para manipulação de tarefas, como buscar todas as tarefas, criar uma nova tarefa, editar uma tarefa existente ou excluir uma tarefa. O serviço utiliza o repositório de tarefas para persistir os dados no banco de dados.
- Repositório de Tarefas: O repositório de tarefas fornece métodos para acesso e manipulação de dados de tarefas no banco de dados. O repositório utiliza a tecnologia JPA para interagir com o banco de dados.
Discussão
A arquitetura MVC com Spring Boot se destaca como uma escolha robusta e flexível para o desenvolvimento de aplicações web modernas. A separação de responsabilidades entre os componentes Model, View e Controller facilita o desenvolvimento, a testabilidade e a manutenção da aplicação. O Spring Boot, por sua vez, oferece um conjunto abrangente de ferramentas para simplificar a implementação e o gerenciamento da aplicação.
Vantagens da Arquitetura MVC com Spring Boot
- Separação de Responsabilidades: A clara divisão de responsabilidades facilita o desenvolvimento, a testabilidade e a manutenção da aplicação.
- Reusabilidade de Componentes: Os componentes do MVC podem ser reutilizados em diferentes partes da aplicação ou em outros projetos, promovendo código modular e eficiente.
- Maior Testabilidade: A separação de responsabilidades facilita a criação de testes unitários para Controllers, testes de integração para verificação da interação entre camadas e testes de UI para garantir o comportamento correto da interface do usuário.
- Flexibilidade e Escalabilidade: A arquitetura MVC se adapta facilmente a mudanças nos requisitos da aplicação, permitindo a adição de novas funcionalidades e o dimensionamento da aplicação para atender a demandas crescentes.
- Desenvolvimento Ágil: O Spring Boot simplifica a configuração e o desenvolvimento, permitindo aos desenvolvedores focarem na lógica de negócio e na implementação rápida de funcionalidades.
- Testabilidade Aprimorada: A separação de responsabilidades facilita a criação de testes unitários para Controllers, testes de integração para verificação da interação entre camadas e testes de UI para garantir o comportamento correto da interface do usuário.
- Manutenção Simplificada: A arquitetura modular facilita a identificação e correção de erros, bem como a adição de novas funcionalidades sem afetar outras partes da aplicação.
- Escalabilidade e Performance: O Spring Boot oferece recursos para construir aplicações altamente performáticas e escaláveis, permitindo lidar com grandes volumes de usuários e transações.
Desafios e Limitações
Apesar das vantagens significativas, a arquitetura MVC com Spring Boot também apresenta alguns desafios:
- Curva de Aprendizagem: A compreensão profunda da arquitetura MVC e do Spring Boot exige um investimento inicial de tempo e estudo.
- Complexidade: A implementação de uma aplicação complexa com MVC e Spring Boot pode ser desafiadora, exigindo um bom entendimento de design de software e boas práticas de desenvolvimento.
- Depuração: A depuração de erros em aplicações complexas com MVC e Spring Boot pode ser complexa, exigindo ferramentas e técnicas específicas.
Recomendações e Boas Práticas
Para aproveitar ao máximo os benefícios da arquitetura MVC com Spring Boot, algumas recomendações e boas práticas podem ser seguidas:
- Seguir os princípios do SOLID: Os princípios do SOLID (Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation e Dependency Inversion) podem ser utilizados para garantir a qualidade e a maintainability do código.
- Utilizar testes unitários e de integração: A criação de testes unitários para Controllers, serviços e repositórios, bem como testes de integração para verificar a interação entre camadas, é crucial para garantir a qualidade e confiabilidade da aplicação.
- Documentar o código: A documentação do código com comentários claros e explicativos facilita a compreensão e a manutenção da aplicação por outros desenvolvedores.
- Seguir as boas práticas do Spring Boot: Adotar as boas práticas recomendadas pelo Spring Boot garante que a aplicação esteja em conformidade com os padrões e práticas recomendadas para o framework.
- Utilizar ferramentas de depuração: Ferramentas de depuração específicas para Java e Spring Boot podem ser úteis para identificar e solucionar problemas na aplicação.
Impacto na Produtividade e Qualidade do Software
A adoção da arquitetura MVC com Spring Boot pode trazer diversos benefícios para a produtividade e qualidade do software:
- Redução do Tempo de Desenvolvimento: O Spring Boot simplifica o desenvolvimento, permitindo que os desenvolvedores se concentrem na lógica de negócio e na implementação de funcionalidades.
- Menos Erros: A separação de responsabilidades do MVC e os recursos de teste do Spring Boot podem reduzir o número de erros na aplicação.
- Maior Facilidade de Manutenção: A arquitetura modular do MVC e a documentação clara do código facilitam a manutenção da aplicação, reduzindo o tempo e o custo de correção de erros.
- Aplicações Mais Escaláveis: O Spring Boot oferece recursos para construir aplicações escaláveis que podem atender às demandas crescentes de usuários e transações.
Considerações Finais
A arquitetura MVC com Spring Boot se consolida como uma ferramenta poderosa para o desenvolvimento de aplicações web modernas, oferecendo uma combinação de flexibilidade, escalabilidade, maintainability e performance. Ao dominar os conceitos e ferramentas dessa abordagem, os desenvolvedores podem construir aplicações robustas, confiáveis e que atendem às demandas complexas da engenharia de software moderna.
Referências
- [Livro] Spring in Action (6ª Edição): Autor: Craig Walls. Editora: Manning
- [Livro] Domain-Driven Design: Implementing Strategic Software (2ª Edição): Autores: Eric Evans, Rebecca Parsons. Editora: Addison-Wesley.
- [Livro] Spring Boot in Action (2ª Edição): Autores: Craig Walls, Brian DeBates. Editora: Manning Publications.
- [Artigo] The Java EE 7 Tutorial (7ª Edição): Autores: Murakatsu Murase, Cindy Lin, Eric J. Hoffman. Editora: Pearson Education.
- [Documentação] Spring Security Reference Documentation: https://docs.spring.io/spring-security/reference/index.html
- [Documentação] Spring Data JPA Reference Documentation: https://docs.spring.io/spring-data/jpa/docs/current-SNAPSHOT/reference/html/



