A sequência de hibernação não existe


87

Tentei atualizar o modo de hibernação de 4 para 5 em meu projeto com a 4.2versão de primavera . Após essa atualização, encontrei o seguinte erro em meu rastreamento de pilha quando chamei um método para atualização.

10:53:32,185 ERROR TableStructure:149 - could not read a hi value
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'test.hibernate_sequence' doesn't exist 

Eu mudei o Id incrementado automaticamente com anotação

@GeneratedValue(strategy=GenerationType.AUTO) 

ainda assim o erro permanece.


4
tente definir no arquivo de configuração `<prop key =" hibernate.id.new_generator_mappings "> false </prop>
Eva Mariam

Respostas:


122

Você também pode colocar:

@GeneratedValue(strategy = GenerationType.IDENTITY)

E deixe o DateBase gerenciar a incrementação da chave primária:

AUTO_INCREMENT PRIMARY KEY

13
Isso pode ser bom em alguns casos, mas tem uma desvantagem óbvia: cada INSERTum vai causar uma viagem de ida e volta adicional ao banco de dados para buscar o ID. Então, quando essa desvantagem for aceitável, tudo bem.
G. Demecki

@ G.Demecki, você poderia discutir os prós e os contras de usar o gerador de identidade do Hibernates em comparação com este método de ida e volta? Seria muito útil!
Jordan Mackie

82

Você precisa definir para Hibernate5.x <property name="hibernate.id.new_generator_mappings">false</property>.. veja e link .

Para versões anteriores do Hibernate 4.x: <prop key="hibernate.id.new_generator_mappings">false</prop>


onde isso é adicionado?
Samuel Thompson

1
adicione isso nas propriedades de hibernação.
rParvathi


9
Sua resposta pode ser a solução para a pergunta, mas não explica por que resolve o problema. Lembre-se de que os links tendem a morrer.
Clijsters

50

Trabalhando com Spring Boot

Solução

Coloque a string abaixo em .application.properties

spring.jpa.properties.hibernate.id.new_generator_mappings=false

Explicação

No Hibernate 4.X, esse atributo é padronizado como true.


29

Esta é a razão por trás desse erro:

Ele procurará como o banco de dados que você está usando gera ids. Para MySql ou HSQSL, existem campos de incremento que incrementam automaticamente. No Postgres ou Oracle, eles usam tabelas de sequência. Como você não especificou um nome de tabela de sequência, ele irá procurar por uma tabela de sequência chamada hibernate_sequence e usá-la como padrão. Portanto, você provavelmente não tem essa tabela de sequência em seu banco de dados e agora obtém esse erro.


1
deve ser marcada como uma resposta, pois isso explica as coisas de forma simples - claro, uma adição de "spring.jpa.properties.hibernate.id.new_generator_mappings = false" deve ser mencionada, mas obrigado.
nightfury

15

Eu estava recebendo o mesmo erro "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Tabela 'mylocaldb.hibernate_sequence' não existe".

Usando spring mvc 4.3.7 e hibernate versão 5.2.9, a aplicação é feita usando a configuração baseada em Spring Java. Agora tenho que adicionar a hibernate.id.new_generator_mappingspropriedade mencionada por @Eva Mariam em meu código assim:

@Autowired
    @Bean(name = "sessionFactory")
    public SessionFactory getSessionFactory(DataSource dataSource) {

        LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
        sessionBuilder.addProperties(getHibernateProperties());
        sessionBuilder.addAnnotatedClasses(User.class);

        return sessionBuilder.buildSessionFactory();
    }

    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
        properties.put("hibernate.id.new_generator_mappings","false");
        return properties;
    }

E funcionou como um encanto.


14

Para sua informação

Se você estiver usando arquivos hbm para definir o mapeamento O / R.

Notar que:

No Hibernate 5, o nome do parâmetro para o nome da sequência foi alterado .

A seguinte configuração funcionou bem no Hibernate 4 :

<generator class="sequence">
    <param name="sequence">xxxxxx_seq</param>
</generator>

Mas no Hibernate 5 , o mesmo arquivo de configuração de mapeamento causará um erro "hibernate_sequence não existe".

Para corrigir esse erro, o nome do parâmetro deve mudar para:

<generator class="sequence">
    <param name="sequence_name">xxxxxx_seq</param>
</generator>

Esse problema me custou 2, 3 horas.

E de alguma forma, parece que não há nenhum documento sobre isso.

Eu tenho que ler o código-fonte de org.hibernate.id.enhanced.SequenceStyleGenerator para descobrir


7

Quando você usa

@GeneratedValue(strategy=GenerationType.AUTO)

ou

@GeneratedValue que é uma forma resumida do acima, o Hibernate começa a decidir a melhor estratégia de geração para você, neste caso ele selecionou

GenerationType.SEQUENCE como a estratégia e é por isso que está procurando

schemaName.hibernate_sequence que é uma tabela, para geração de id baseada em sequência.

Quando você usa GenerationType.SEQUENCEcomo estratégia, você precisa fornecer o @TableGeneratorseguinte.

     @Id
     @GeneratedValue(strategy = GenerationType.TABLE, generator = "user_table_generator")
     @TableGenerator(name = "user_table_generator",
                table = "user_keys", pkColumnName = "PK_NAME", valueColumnName = "PK_VALUE")
     @Column(name = "USER_ID")
     private long userId;

Quando você define a estratégia, ela é

@GeneratedValue(strategy = GenerationType.IDENTITY) .

o problema original é resolvido porque o Hibernate para de procurar a tabela de sequência.


6

No caso de alguém arrancar os cabelos com esse problema como eu fiz hoje, não pude resolver esse erro até que mudei

spring.jpa.hibernate.dll-auto=create

para

spring.jpa.properties.hibernate.hbm2ddl.auto=create

5

no hibernate 5.x, você deve adicionar set hibernate.id.new_generator_mappings para false em hibernate.cfg.xml

<session-factory>
    ......
    <property name="show_sql">1</property>
    <property name="hibernate.id.new_generator_mappings">false</property>
     ......
 </session-factory>

2

Você também pode colocar:

@GeneratedValue(strategy = GenerationType.IDENTITY)

E deixe o DateBase gerenciar a incrementação da chave primária:

AUTO_INCREMENT PRIMARY KEY

A resposta acima me ajudou.


1

Se você estiver usando a versão do Hibernate anterior ao Hibernate5 @GeneratedValue(strategy = GenerationType.IDENTITY)funciona perfeitamente. Mas após o Hibernate5, a seguinte correção é necessária.

@Id
@GeneratedValue(strategy= GenerationType.AUTO,generator="native")
@GenericGenerator(name = "native",strategy = "native")
private Long id;

DDL

`id` BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY

RAZÃO

Trecho do hibernate-issue

Atualmente, se hibernate.id.new_generator_mappings estiver definido como falso, @GeneratedValue (estratégia = GenerationType.AUTO) será mapeado para nativo. Se esta propriedade for verdadeira (que é o valor padrão em 5.x), o @GeneratedValue (estratégia = GenerationType.AUTO) é sempre mapeado para SequenceStyleGenerator.

Por esta razão, em qualquer banco de dados que não suporte sequências nativamente (por exemplo, MySQL), vamos usar o gerador TABLE em vez de IDENTITY.

No entanto, o gerador TABLE, embora mais portátil, usa uma transação separada sempre que um valor está sendo obtido do banco de dados. Na verdade, mesmo que o IDENTITY desative as atualizações em lote do JDBC e o gerador TABLE use o otimizador em pool, o IDENTITY ainda é melhor escalonado.


0

Isso pode ser causado por HHH-10876, que foi corrigido, portanto, certifique-se de atualizar para:

  • Hibernate ORM 5.2.1,
  • Hibernate ORM 5.1.1,
  • Hibernate ORM 5.0.11

1
Estou usando Spring-data-jpa que internamente está usando Hibernate 5.2.17.Finalcomo uma implementação. Ainda estou tendo esse problema quando GenerationTypeé AUTO.
TheCoder

0

Eu adicionei a sequência do Hibernate no postgres. Execute esta consulta no Editor PostGres:

    CREATE SEQUENCE hibernate_sequence
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 2
  CACHE 1;
ALTER TABLE hibernate_sequence
  OWNER TO postgres;

Vou descobrir os prós / contras de usar a consulta, mas para quem precisa de ajuda pode usar isso.


0

No meu caso, substituir todas as anotações GenerationType.AUTOpor GenerationType.SEQUENCEresolveu o problema.


-2

Execute esta consulta

create sequence hibernate_sequence start with 1 increment by 1

Solicite que você compartilhe os detalhes de como ele resolve o problema e sua resposta é melhor do que as outras respostas ...
Suraj Kumar
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.