5. Introdução ao Spring Data JPA
Neste capítulo, iremos examinar a seguinte arquitetura:
![]() |
Inserimos uma camada [JPA] (Java Persistence API) entre a camada [DAO] e o controlador JDBC do SGBD. A partir de agora, a camada JPA emite os comandos SQL destinados ao SGBD. A camada [DAO] já não lida com comandos SQL, mas apenas com objetos chamados entidades JPA, que são representações das várias tabelas na base de dados em utilização. Os campos destas entidades estão associados de forma única às colunas das tabelas através de anotações Java. É isto que permite à camada JPA traduzir as operações da camada [DAO] sobre as entidades JPA para SQL.
O Spring Data é um ramo do Spring focado no acesso a dados, quer os dados estejam armazenados num SGBDR, numa base de dados NoSQL ou noutros tipos de armazenamento. Aqui, estamos apenas preocupados com SGBDR e com o acesso aos mesmos através do JPA. Mais adiante, por vezes escreveremos [Spring JPA] para nos referirmos, na verdade, ao [Spring Data JPA]. Na arquitetura acima, a camada [Spring Data] fornece à camada [DAO] ferramentas para gerir entidades JPA.
O JPA é, na verdade, uma especificação. Iremos testar três das suas implementações:
- Hibernate (http://hibernate.org/);
- EclipseLink (http://www.eclipse.org/eclipselink/);
- OpenJpa (http://openjpa.apache.org/);
5.1. Exemplo-01
O site do Spring oferece vários tutoriais para começar a utilizar o Spring [http://spring.io/guides]. Iremos utilizar um deles para apresentar o Spring Data. Para tal, iremos utilizar o Spring Tool Suite (STS).
![]() |
- Em [1], importamos um dos tutoriais de [spring.io/guides];
![]() |
- Em [2], selecionamos o tutorial [Acesso a dados JPA], que demonstra como aceder a uma base de dados utilizando o Spring Data;
- Em [3], selecionamos um projeto configurado pelo Maven;
- em [4], o tutorial está disponível em duas formas: [initial], que é uma versão vazia que preenche seguindo o tutorial, ou [complete], que é a versão final do tutorial. Escolhemos a última;
- Em [5], pode optar por visualizar o tutorial num navegador;
- Em [6], o projeto final.
5.1.1. A configuração Maven do projeto
As dependências Maven do projeto estão configuradas no ficheiro [pom.xml]:
<groupId>org.springframework</groupId>
<artifactId>gs-accessing-data-jpa</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
<properties>
<!-- use UTF-8 for everything -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<start-class>hello.Application</start-class>
</properties>
- linhas 5–9: definem um projeto Maven pai. Este projeto define a maioria das dependências do projeto. Estas podem ser suficientes, caso em que não são adicionadas dependências adicionais, ou podem não ser, caso em que as dependências em falta são adicionadas;
- linhas 12–15: definem uma dependência do [spring-boot-starter-data-jpa]. Este artefacto contém as classes Spring Data;
- Linhas 16–19: definem uma dependência do SGBD H2, que permite criar e gerir bases de dados na memória.
Vejamos as classes fornecidas por estas dependências:
![]() | ![]() | ![]() |
São muitas:
- algumas pertencem ao ecossistema Spring (aquelas que começam por spring);
- outros pertencem ao ecossistema Hibernate (hibernate, jboss), cuja implementação JPA estamos a utilizar aqui;
- outras são bibliotecas de testes (junit, hamcrest);
- outras são bibliotecas de registo (log4j, logback, slf4j);
Vamos mantê-las todas. Para uma aplicação de produção, apenas as necessárias devem ser mantidas.
Na linha 26 do ficheiro [pom.xml], encontramos a linha:
<start-class>hello.Application</start-class>
Esta linha está ligada às seguintes linhas:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Linhas 6–9: O [spring-boot-maven-plugin] permite gerar o JAR executável da aplicação. A linha 26 do ficheiro [pom.xml] especifica então a classe executável deste JAR.
5.1.2. A camada [JPA]
O acesso à base de dados é tratado através de uma camada [JPA], a Java Persistence API:
![]() |
![]() |
A aplicação é básica e gere entidades [Cliente]. A classe [Cliente] faz parte da camada [JPA] e tem a seguinte estrutura:
package hello;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
protected Customer() {
}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
}
}
Um cliente tem um ID [id], um nome próprio [firstName] e um apelido [lastName]. Cada instância [Customer] representa uma linha numa tabela de base de dados.
- linha 8: Anotação JPA que garante que a persistência das instâncias [Customer] (Criar, Ler, Atualizar, Eliminar) será gerida por uma implementação JPA. Com base nas dependências do Maven, podemos ver que está a ser utilizada a implementação JPA/Hibernate;
- Linhas 11–12: Anotações JPA que associam o campo [id] à chave primária da tabela [Customer]. A linha 12 indica que a implementação JPA utilizará o método de geração de chave primária específico do SGBD em uso, neste caso o H2;
Não existem outras anotações JPA. Serão, portanto, utilizados valores por defeito:
- a tabela [Customer] receberá o nome da classe, ou seja, [Customer];
- as colunas desta tabela receberão nomes baseados nos campos da classe: [id, firstName, lastName], observando-se que as maiúsculas e minúsculas não são levadas em conta nos nomes das colunas da tabela;
Note-se que a implementação JPA utilizada nunca é nomeada.
5.1.3. A camada [Spring Data]
A classe [CustomerRepository] implementa a camada de acesso para a tabela [Customer]. O seu código é o seguinte:
![]() |
![]() |
package hello;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
Trata-se, portanto, de uma interface e não de uma classe (linha 7). Ela estende a interface [CrudRepository], uma interface do Spring Data (linha 5). Esta interface é parametrizada por dois tipos: o primeiro é o tipo dos elementos geridos, neste caso o tipo [Customer]; o segundo é o tipo da chave primária dos elementos geridos, neste caso um tipo [Long]. A interface [CrudRepository] é a seguinte:
package org.springframework.data.repository;
import java.io.Serializable;
@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity);
<S extends T> Iterable<S> save(Iterable<S> entities);
T findOne(ID id);
boolean exists(ID id);
Iterable<T> findAll();
Iterable<T> findAll(Iterable<ID> ids);
long count();
void delete(ID id);
void delete(T entity);
void delete(Iterable<? extends T> entities);
void deleteAll();
}
Esta interface define as operações CRUD (Criar – Ler – Atualizar – Eliminar) que podem ser realizadas num tipo JPA T:
- linha 8: o método save permite que uma entidade T seja persistida na base de dados. Ele persiste a entidade utilizando a chave primária que lhe foi atribuída pelo SGBD. Também permite que uma entidade T identificada pela sua chave primária id seja atualizada. A escolha entre estas duas ações depende do valor da chave primária id: se for nulo, ocorre a operação de persistência; caso contrário, ocorre a operação de atualização;
- linha 10: igual ao acima, mas para uma lista de entidades;
- linha 12: o método findOne recupera uma entidade T identificada pela sua chave primária id;
- linha 22: o método delete permite eliminar uma entidade T identificada pela sua chave primária id;
- linhas 24–28: variações do método [delete];
- linha 16: o método [findAll] recupera todas as entidades T persistentes;
- linha 18: igual ao anterior, mas limitado às entidades para as quais foi fornecida uma lista de identificadores;
Voltemos à interface [CustomerRepository]:
package hello;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
- A linha 9 permite-lhe recuperar um [Cliente] pelo seu [apelido];
E é tudo quanto à camada [DAO]. Não existe uma classe de implementação para a interface anterior. Esta é gerada em tempo de execução pelo [Spring Data]. Os métodos da interface [CrudRepository] são implementados automaticamente. Quanto aos métodos adicionados à interface [CustomerRepository], depende. Voltemos à definição de [Customer]:
private long id;
private String firstName;
private String lastName;
O método na linha 9 é implementado automaticamente pelo [Spring Data] porque faz referência ao campo [lastName] (linha 3) de [Customer]. Quando encontra um método [findBySomething] na interface a ser implementada, o Spring Data implementa-o utilizando a seguinte consulta JPQL (Java Persistence Query Language):
Portanto, o tipo T deve ter um campo chamado [something]. Assim, o método
será implementado com código semelhante ao seguinte:
return [em].createQuery("select c from Customer c where c.lastName=:value").setParameter("value",lastName).getResultList()
onde [em] se refere ao contexto de persistência JPA. Isto só é possível se a classe [Customer] tiver um campo chamado [lastName], o que é o caso.
Em conclusão, em casos simples, o Spring Data permite-nos implementar a camada [DAO] com uma interface simples.
5.1.4. A camada [console]
![]() |
![]() |
A classe [Application] é a seguinte:
package hello;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
CustomerRepository repository;
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
@Override
public void run(String... strings) throws Exception {
// save a couple of customers
repository.save(new Customer("Jack", "Bauer"));
repository.save(new Customer("Chloe", "O'Brian"));
repository.save(new Customer("Kim", "Bauer"));
repository.save(new Customer("David", "Palmer"));
repository.save(new Customer("Michelle", "Dessler"));
// fetch all customers
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Customer customer : repository.findAll()) {
System.out.println(customer);
}
System.out.println();
// fetch an individual customer by ID
Customer customer = repository.findOne(1L);
System.out.println("Customer found with findOne(1L):");
System.out.println("--------------------------------");
System.out.println(customer);
System.out.println();
// fetch customers by last name
System.out.println("Customer found with findByLastName('Bauer'):");
System.out.println("--------------------------------------------");
for (Customer bauer : repository.findByLastName("Bauer")) {
System.out.println(bauer);
}
}
}
- linha 9: a classe implementa a interface [CommandLineRunner], que é uma interface [Spring Boot] (linha 4). Esta interface tem apenas um método, o que se encontra na linha 19;
- linha 8: @SpringBootApplication é uma anotação que agrupa várias anotações [Spring Boot]:
- @Configuration: indica que a classe é uma classe de configuração;
- @EnableAutoConfiguration: instrui o [Spring Boot] a criar automaticamente vários beans com base em diversas propriedades, particularmente o conteúdo do classpath do projeto. Como as bibliotecas do Hibernate estão no Classpath, o bean [entityManagerFactory] será implementado utilizando o Hibernate. Como a biblioteca do SGBD H2 está no Classpath, o bean [dataSource] será implementado utilizando o H2. No bean [dataSource], devemos também definir o nome de utilizador e a palavra-passe. Aqui, o Spring Boot utilizará o administrador H2 predefinido, que não tem palavra-passe. Como a biblioteca [spring-tx] está no Classpath, será utilizado o gestor de transações do Spring;
- @EnableWebMvc: se a biblioteca [spring-mvc] estiver no Classpath. Neste caso, é realizada a configuração automática para a aplicação web;
- @ComponentScan: que indica ao Spring onde procurar outros beans, configurações e serviços. Aqui, estes são procurados por predefinição no pacote que contém a classe anotada, ou seja, o pacote [hello]. Assim, as classes [Customer] e [CustomerRepository] serão encontradas. Como a primeira tem a anotação [@Entity], será catalogada como uma entidade a ser gerida pelo Hibernate. Como a segunda estende a interface [CrudRepository], será registada como um bean do Spring;
- linhas 11–12: o bean [CustomerRepository] é injetado no código da classe principal;
- linha 15: o método estático [run] da classe [SpringApplication] do projeto Spring Boot é executado. O seu parâmetro é a classe que possui uma anotação [Configuration] ou [EnableAutoConfiguration]. Tudo o que foi explicado anteriormente ocorrerá então. O resultado é um contexto de aplicação Spring, ou seja, um conjunto de beans geridos pelo Spring;
- linhas 19–48: as operações seguintes utilizam simplesmente os métodos do bean que implementa a interface [CustomerRepository];
A saída da consola é a seguinte:
- Linhas 1-8: o logótipo do projeto Spring Boot;
- linha 9: a classe [hello.Application] é executada;
- linha 10: [AnnotationConfigApplicationContext] é uma classe que implementa a interface [ApplicationContext] do Spring. É um contentor de beans;
- linha 11: o bean [entityManagerFactory] é implementado com a classe [LocalContainerEntityManagerFactory], uma classe do Spring. Esta classe gere a camada [JPA];
- linha 12: aparece [Hibernate]. Esta é a implementação JPA escolhida;
- linha 19: um dialeto Hibernate é a variante SQL a ser utilizada com o SGBD. Aqui, o dialeto [H2Dialect] indica que o Hibernate irá funcionar com o SGBD H2;
- linhas 21–22: a base de dados é criada. A tabela [CUSTOMER] é criada. Isto significa que o Hibernate foi configurado para gerar tabelas a partir de definições JPA, neste caso a definição JPA da classe [Customer];
- linhas 26–30: resultado do método [findAll] da interface;
- linha 34: resultado do método [findOne] da interface;
- linhas 38–39: resultados do método [findByLastName];
- linhas 41 e seguintes: registos do encerramento do contexto Spring.
5.1.5. Configuração manual do projeto Spring Data
Duplicamos o projeto anterior para o projeto [gs-accessing-data-jpa-02]:
![]() |
Neste novo projeto, não vamos utilizar a configuração automática fornecida pelo Spring Boot. Vamos configurá-lo manualmente. Isto pode ser útil se as configurações padrão não se adequarem às nossas necessidades.
Primeiro, vamos especificar as dependências necessárias no ficheiro [pom.xml]:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-accessing-data-jpa-02</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
</parent>
<dependencies>
<!-- Spring Data -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<!-- H2 Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- Tomcat JDBC -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
</dependencies>
<properties>
<!-- use UTF-8 for everything -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</repository>
<repository>
<id>org.jboss.repository.releases</id>
<name>JBoss Maven Release Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
- linhas 10–14: o projeto Maven pai cujas bibliotecas iremos utilizar;
- linhas 18–21: Spring Data utilizado para aceder à base de dados;
- linhas 23–26: a implementação do Hibernate da especificação JPA;
- linhas 28–31: o SGBD H2;
- linhas 33–36: as bases de dados são frequentemente utilizadas com pools de ligações, o que evita a abertura e o encerramento repetidos de ligações. Aqui, a implementação utilizada é [tomcat-jdbc];
No novo projeto, a entidade [Customer] e a interface [CustomerRepository] permanecem inalteradas. Iremos modificar a classe [Application], que será dividida em duas classes:
- [Config], que será a classe de configuração;
- [Main], que será a classe executável;
![]() |
A classe executável [Application] fica agora da seguinte forma:
package console;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import repositories.CustomerRepository;
import config.AppConfig;
import entities.Customer;
public class Application {
public static void main(String[] args) {
// instantiation Spring context
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
CustomerRepository repository = context.getBean(CustomerRepository.class);
// save a couple of customers
repository.save(new Customer("Jack", "Bauer"));
repository.save(new Customer("Chloe", "O'Brian"));
repository.save(new Customer("Kim", "Bauer"));
repository.save(new Customer("David", "Palmer"));
repository.save(new Customer("Michelle", "Dessler"));
...
// closing context
context.close();
}
}
- linha 9: a classe [Application] já não tem quaisquer anotações de configuração;
- linhas 3–7: Note que já não existem importações do pacote [Spring Boot];
- linha 12: Instanciamos os beans do Spring. Obtemos o contexto do Spring, que contém referências aos beans criados;
- linha 13: solicitamos uma referência ao bean [CustomerRepository];
A classe [ Config] que configura o projeto é a seguinte:
package config;
import javax.persistence.EntityManagerFactory;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "repositories" })
@Configuration
// @ComponentScan(basePackages={"package1","package2"})
public class AppConfig {
// h2 database
@Bean
public DataSource dataSource() {
// data source TomcatJdbc
DataSource dataSource = new DataSource();
// configuration access JDBC
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUrl("jdbc:h2:./demo");
dataSource.setUsername("sa");
dataSource.setPassword("");
// an initially open connection
dataSource.setInitialSize(1);
// result
return dataSource;
}
// the provider JPA
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.H2);
return hibernateJpaVendorAdapter;
}
// EntityManagerFactory
@Bean
public EntityManagerFactory entityManagerFactory(JpaVendorAdapter jpaVendorAdapter, DataSource dataSource) {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(jpaVendorAdapter);
factory.setPackagesToScan("entities");
factory.setDataSource(dataSource);
factory.afterPropertiesSet();
return factory.getObject();
}
// Transaction manager
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory);
return txManager;
}
}
- linha 17: a anotação [@EnableTransactionManagement] indica que as anotações [@Transactional] devem ser interpretadas. Os métodos das interfaces [CrudRepository] possuem essas anotações. Por conseguinte, são executados dentro de uma transação;
- linha 18: a anotação [@EnableJpaRepositories] especifica os diretórios onde se encontram as interfaces [CrudRepository] do Spring Data. Estas interfaces tornar-se-ão componentes Spring e estarão disponíveis no contexto Spring;
- linha 19: a anotação [@Configuration] torna a classe [Config] uma classe de configuração do Spring;
- linha 20: a anotação [@ComponentScan] lista os diretórios onde os componentes Spring devem ser procurados. Os componentes Spring são classes anotadas com anotações Spring, tais como @Service, @Component, @Controller, etc. Aqui, não existem outros além dos definidos na classe [AppConfig], pelo que a anotação foi comentada;
- Linhas 24–37: definem a fonte de dados, a base de dados H2. É a anotação @Bean na linha 25 que torna o objeto criado por este método um componente gerido pelo Spring. O nome do método pode ser qualquer um aqui. No entanto, deve ser denominado [dataSource] se a EntityManagerFactory na linha 51 estiver ausente e for definida através da configuração automática;
- linha 30: a base de dados será denominada [demo] e será gerada na pasta do projeto;
- Linhas 40–47: definem a implementação JPA utilizada, neste caso uma implementação Hibernate. O nome do método pode ser qualquer um aqui;
- linha 43: sem registos SQL;
- linha 44: a base de dados será criada se não existir;
- linhas 50–58: definem o EntityManagerFactory que irá gerir a persistência JPA. O método deve ser denominado [entityManagerFactory];
- linha 51: o método recebe dois parâmetros dos tipos dos dois beans definidos anteriormente. Estes serão então construídos e injetados pelo Spring como parâmetros do método;
- linha 53: define a implementação JPA a ser utilizada;
- linha 54: especifica os diretórios onde as entidades JPA podem ser encontradas;
- linha 55: define a fonte de dados a ser gerida;
- linhas 61–66: o gestor de transações. O método deve ser denominado [transactionManager]. Recebe o bean das linhas 51–58 como parâmetro;
- linha 64: o gestor de transações é associado ao EntityManagerFactory;
Os métodos anteriores podem ser definidos em qualquer ordem.
A execução do projeto produz os mesmos resultados. Um novo ficheiro aparece na pasta do projeto, o ficheiro da base de dados H2:
![]() |
5.1.6. Criação de um arquivo executável
Para criar um arquivo executável do projeto, proceda da seguinte forma:
![]() |
- em [1]: crie uma configuração de tempo de execução;
- em [2]: do tipo [Aplicação Java]
- em [3]: especifique o projeto a executar (utilize o botão Procurar);
- em [4]: especifique a classe a ser executada;
- em [5]: o nome da configuração de execução — pode ser qualquer nome;
![]() |
- em [6]: exportar o projeto;
- em [7]: como um arquivo JAR executável;
- em [8]: especifique o caminho e o nome do ficheiro executável a ser criado;
- em [9]: o nome da configuração de execução criada em [5];
10 ![]() |
- em [10], o arquivo criado;
Depois de fazer isso, abra um terminal na pasta que contém o arquivo executável:
O arquivo é executado da seguinte forma:
.....\dist>java -jar gs-accessing-data-jpa-02.jar
Os resultados apresentados na consola são os seguintes:
5.1.7. Criação de um projeto [Spring Data]
Para criar um modelo de projeto Spring Data, siga estes passos:
![]() |
- Em [1], crie um novo projeto;
- em [2]: selecione [Spring Starter Project];
- O projeto gerado será um projeto Maven. Em [3], especifique o nome do grupo do projeto;
- Em [4], especifique o nome do artefacto (um JAR, neste caso) que será criado quando o projeto for compilado;
- em [5]: o nome do projeto no Eclipse — pode ser qualquer coisa (não precisa de corresponder a [4]);
- em [7]: especifique que está a criar um projeto com uma camada [JPA] utilizando o SGBD MySQL. As dependências necessárias para tal projeto serão então incluídas no ficheiro [pom.xml];
![]() |
- em [8], introduza o nome da pasta do projeto;
- em [9], conclua o assistente;
![]() |
- em [10]: o projeto criado;
O ficheiro [pom.xml] inclui as dependências necessárias para um projeto JPA:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>istia.st.springdata</groupId>
<artifactId>intro-spring-data-01</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>intro-spring-data-01</name>
<description>démo spring data avec table de produits</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.IntroSpringData01Application</start-class>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- linhas 14–19: o projeto Maven pai;
- linhas 28–31: a dependência necessária para o JPA – incluirá [Spring Data];
- linhas 32–36: a dependência do controlador JDBC do MySQL;
- linhas 37–41: dependências necessárias para os testes JUnit integrados com o Spring;
A classe executável [Application] não faz nada, mas está pré-configurada:
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class IntroSpringData01Application {
public static void main(String[] args) {
SpringApplication.run(IntroSpringData01Application.class, args);
}
}
- A anotação [@SpringBootApplication] torna a classe uma classe de configuração automática do projeto;
A classe de teste [ApplicationTests] não faz nada, mas está pré-configurada:
package demo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = IntroSpringData01Application.class)
public class IntroSpringData01ApplicationTests {
@Test
public void contextLoads() {
}
}
- linha 9: a anotação [@SpringApplicationConfiguration] permite que o ficheiro de configuração [IntroSpringData01Application] seja utilizado. A classe de teste irá, assim, beneficiar de todos os beans definidos por este ficheiro;
- linha 8: a anotação [@RunWith] permite a integração do Spring com o JUnit: a classe poderá ser executada como um teste JUnit. [@RunWith] é uma anotação do JUnit (linha 4), enquanto a classe [SpringJUnit4ClassRunner] é uma classe do Spring (linha 6);
Agora que temos um esqueleto de aplicação JPA, podemos completá-lo.




















