Hibernate criando automaticamente uma tabela adicional chamada hibernate_sequence e tentando inserir dados nela, ao invés de inserir onde estou informando no método main

Fala pessoal, tudo certo?

Estou com um “problema” com o Hibernate. Digo problema pois não consegui identificar o que está ocorrendo, porém acredito que possa ser algo relacionado com a propriedade hibernate.hbm2ddl.auto ou talvez com esta versão do Hibernate que estou utilizando.

Mapeei as classes que eu quero criar automaticamente com o Hibernate. Até aí tudo certo. Ele cria as tabelas normalmente no banco de dados, mas logo após criar minhas tabelas, ele cria automaticamente uma outra tabela chamada de hibernate_sequence, e por fim, tenta fazer o insert nessa última tabela, ao invés de inserir na tabela que estou informando no método main (testes).

Alguém já passou por isso e poderia me dar um help?

Trecho do retorno no console:

Mar 18, 2021 12:25:09 AM org.hibernate.jpa.boot.spi.ProviderChecker hibernateProviderNamesContain
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; [org.hibernate.jpa.HibernatePersistenceProvider] will be used instead.
Mar 18, 2021 12:25:09 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [name: PedidoPU]
Mar 18, 2021 12:25:09 AM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate ORM core version 5.4.29.Final
Mar 18, 2021 12:25:09 AM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
Mar 18, 2021 12:25:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
Mar 18, 2021 12:25:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://localhost/cursojavaee]
Mar 18, 2021 12:25:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {password=****, user=root}
Mar 18, 2021 12:25:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
Mar 18, 2021 12:25:09 AM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Mar 18, 2021 12:25:09 AM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Mar 18, 2021 12:25:10 AM org.hibernate.resource.beans.spi.ManagedBeanRegistryInitiator resolveBeanContainer
INFO: HHH10005002: No explicit CDI BeanManager reference was passed to Hibernate, but CDI is available on the Hibernate ClassLoader.
Hibernate: drop table if exists Cliente
Mar 18, 2021 12:25:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@3d904e9c] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table if exists Endereco
Hibernate: drop table if exists hibernate_sequence
Hibernate: create table Cliente (id bigint not null, documentoReceitaFederal varchar(255), email varchar(255), nome varchar(255), tipo integer, primary key (id)) engine=MyISAM
Mar 18, 2021 12:25:10 AM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@4fc3c165] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create table Endereco (id bigint not null, cep varchar(255), cidade varchar(255), cliente tinyblob, complemento varchar(255), logradouro varchar(255), numero varchar(255), uf varchar(255), primary key (id)) engine=MyISAM
Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: insert into hibernate_sequence values ( 1 )
Mar 18, 2021 12:25:10 AM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService
INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]

Segue meu arquivo persistence.xml:

    <persistence-unit name="PedidoPU">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>

        <properties>

            <!-- Acesso ao banco de dados -->
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/cursojavaee" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />

            <!-- Criar tabelas automaticamente -->
            <property name="hibernate.hbm2ddl.auto" value="create" />

            <!-- Mostrar as queries no console -->
            <property name="hibernate.show_sql" value="true" />

            <!-- Definindo o dialeto para o MySQL (conversão exata de código) -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />

        </properties>
    </persistence-unit>
</persistence>

Também o pom.xml:

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<!-- Núcleo do Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.4.29.Final</version>
			<scope>compile</scope>
		</dependency>

		<!-- Implementação de EntityManager da JPA -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>5.4.29.Final</version>
			<scope>compile</scope>
		</dependency>

		<!-- Driver JDBC do MySQL -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.23</version>
			<scope>compile</scope>
		</dependency>

		<!-- Weld (implementação do CDI) -->
		<dependency>
			<groupId>org.jboss.weld.servlet</groupId>
			<artifactId>weld-servlet</artifactId>
			<version>2.2.9.Final</version>
			<scope>compile</scope>
		</dependency>

		<!-- Weld depende do Jandex -->
		<dependency>
			<groupId>org.jboss</groupId>
			<artifactId>jandex</artifactId>
			<version>1.2.2.Final</version>
			<scope>compile</scope>
		</dependency>

	</dependencies>

	<build>
		<finalName>PedidoVenda</finalName>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<repositories>
		<repository>
			<id>prime-repo</id>
			<name>PrimeFaces Maven Repository</name>
			<url>http://repository.primefaces.org</url>
			<layout>default</layout>
		</repository>
	</repositories>

</project>

E a classe Cliente que deve se tornar uma tabela no banco de dados:

package model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Transient;

@Entity
public class Cliente implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String nome;
    private String email;
    private String documentoReceitaFederal;
    private TipoPessoa tipo;
    private List<Endereco> enderecos = new ArrayList<>(); // melhor instanciar as List<> para evitar problemas de
                                                          // NullPointerException

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getDocumentoReceitaFederal() {
        return documentoReceitaFederal;
    }

    public void setDocumentoReceitaFederal(String documentoReceitaFederal) {
        this.documentoReceitaFederal = documentoReceitaFederal;
    }

    @Transient
    public List<Endereco> getEnderecos() {
        return enderecos;
    }

    public void setEnderecos(List<Endereco> enderecos) {
        this.enderecos = enderecos;
    }

    public TipoPessoa getTipo() {
        return tipo;
    }

    public void setTipo(TipoPessoa tipo) {
        this.tipo = tipo;
    }

    @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;
        Cliente other = (Cliente) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}

O Hibernate com MySQL cria por default essa tabela para armazenar o valor das sequencias. Se queres usar o autoincrement por tabela deves colocar a estratégia IDENTITY na tua anotação de GeneratedValue:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {

1 curtida

Entendi amigo. E também agora me faz sentido a tabela chamada sequences. Tem tudo a ver com autoincrement mesmo.

Vou tentar fazer isso depois e volto aqui pra comentar se obtive algum êxito.

Muito obrigado por ora. :wink:

@pmlm fiz isso que você informou porém aconteceu a mesma coisa que antes.

Pesquisei um pouco aqui e identifiquei que à partir da versão 5 do Hibernate a estratégia é TABLE, ou seja, esta tabela sempre será gerada. Porém na explicação diz que tem problemas de performance.

Sabe se tem alguma forma de desabilitar a geração automática das tabelas de sequência, assim como era nas versões anteriores, que utilizavam a própria coluna Id da tabela (Entity) para ser o auto-increment?

Link desta explicação: https://www.alura.com.br/artigos/entendendo-a-geracao-de-chaves-com-jpa

Exatamente por a partir do Hibernate 5 a estratégia default ser TABLE é que de disse para colocares IDENTITY
Não deverá fazer diferença mas coloca na propriedade em vez do getter

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

Fiz isso também, colocando na propriedade e ocorre a mesma coisa.

O Hibernate cria a tabela hibernate_sequence com a coluna next_val e insere o id 1.

Hibernate: create table hibernate_sequence (next_val bigint) engine=MyISAM
Hibernate: insert into hibernate_sequence values ( 1 )

E na tabela Cliente não insere nada.

Tabelas criadas:
image

Dados da tabela hibernate_sequence:
image

Tabela Cliente:
image

De certeza que está a usar essa versão com a anotação alterada e não uma qualquer compilada anteriormente?

Estou utilizando o hibernate setado no pom.xml mesmo.

Vou fazer o seguinte, vou recriar do zero este projeto e tentar novamente. Volto a postar aqui o resultado.

Obrigado por ora. :wink: