Última atualização: 17/03/2021

Este guia mostra o processo de criação de um projeto Spring e a implementação de uma classe persistente.

O que você vai fazer

O que você vai aprender

O que você precisa

O mapeamento objeto / relacional é a persistência automatizada (e transparente) de objetos em um aplicativo Java para as tabelas em um banco de dados SQL, usando metadados que descrevem o mapeamento entre as classes do aplicativo e o esquema do banco de dados SQL.

Em essência, ORM funciona transformando os dados de uma representação para outra.

Desenvolvedores Java devem ter um nível suficiente de familiaridade com modelagem relacional e SQL para trabalhar com o Hibernate.

Java Persistence API define o seguinte:

Usando o site ou o wizard do STS4 Spring Starter Project, vamos criar um projeto Spring Boot. Vamos usar as seguintes dependências:

Arquivo pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.4.3</version>
                <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.professorangoti</groupId>
        <artifactId>teste-springboot-hibernate</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>teste-springboot-hibernate</name>
        <description>Demo project for Spring Boot</description>
        <properties>
                <java.version>1.8</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>

Para o nosso exemplo vamos usar a seguinte classe Java

public class Categoria {
  private Integer id;
  private String nome;

  // construtor padrão e construtor com todos atributos
  // e getters/setters
}

@Entity

A classe deve ser anotada com a anotação @Entity, que é usada para declarar que a classe representa uma entidade no banco de dados.

import javax.persistence.Entity;

@Entity
public class Categoria { ... }

@Id e @GeneratedValue

@Id – especifica o identificador da entidade. Qualquer entidade precisa ter um atributo identificador, este que é usado ao carregar a entidade.

@GeneratedValue – especifica que o valor do identificador de entidade é gerado automaticamente utilizando a coluna de identidade, uma sequência de banco de dados ou um gerador de tabelas

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

Serializable

A classe deve implementar a interface Serializable. Esta interface permite transformar o objeto em um formato em que os dados do objeto sejam usados de forma externa ao código, com o objetivo de armazenar ou transmitir os dados.

@Entity
public class Categoria implements Serializable {
        private static final long serialVersionUID = 1L;
    ...
}

Os métodos hashCode e equals

A classe deve implementar a interface Serializable e acrescentar dois métodos: hashCode e equals (implementação padrão: somente id)

@Override
public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
}

@Override
public boolean equals(Object obj) {
        if (this == obj)
                return true;
        if (obj == null)
                return false;
        if (getClass() != obj.getClass())
                return false;
        Categoria other = (Categoria) obj;
        if (id == null) {
                if (other.id != null)
                        return false;
        } else if (!id.equals(other.id))
                return false;
        return true;
}

Altere o arquivo /src/main/resources/application.properties:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/teste
spring.datasource.username=root
spring.datasource.password=

spring.jpa.show-sql=true

logging.level.org.springframework.web=trace

A interface central na abstração da camada de acesso a dados do Spring Data é Repository. Esta interface precisa da classe de domínio e o tipo de id da classe de domínio como argumentos de tipo.

@Repository
public interface CategoriaRepository extends JpaRepository<Categoria, Integer>{ }

A declaração dessa interface, ao estender JpaRepository, permite acessar um monte de métodos CRUD genéricos.

Para que o Spring crie um bean que implemente esta interface, tudo que você precisa fazer é usar a anotação @Repository.

Alguns métodos que podemos usar da interface JpaRepository<T, ID> (consulte a lista completa em documentação):

Vamos agora testar a nossa classe persistente usando a interface CommandLineRunner. Veja o código completo da classe TesteSpringbootHibernateApplication

@SpringBootApplication
public class TesteSpringbootHibernateApplication implements CommandLineRunner {

        @Autowired
        CategoriaRepository repo;
        
        public static void main(String[] args) {
                SpringApplication.run(TesteSpringbootHibernateApplication.class, args);
        }

        @Override
        public void run(String... args) throws Exception {
                repo.save(new Categoria(null,"teste"));
                
        }

}