La séquence Hibernate n'existe pas


88

J'ai essayé de mettre à niveau la mise en veille prolongée de 4 à 5 dans mon projet avec la 4.2version printemps . Après cette mise à niveau, j'ai trouvé l'erreur suivante dans ma trace de pile lorsque j'ai appelé une méthode de mise à jour.

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 

J'ai changé l'identifiant incrémenté automatiquement avec une annotation

@GeneratedValue(strategy=GenerationType.AUTO) 

l'erreur persiste.


4
essayez de définir dans le fichier de configuration `<prop key =" hibernate.id.new_generator_mappings "> false </prop>
Eva Mariam

Réponses:


123

Vous pouvez également mettre:

@GeneratedValue(strategy = GenerationType.IDENTITY)

Et laissez la DateBase gérer l'incrémentation de la clé primaire:

AUTO_INCREMENT PRIMARY KEY

13
Cela peut être bon dans certains cas, mais présente un inconvénient évident: tout INSERTva provoquer un aller-retour supplémentaire vers la base de données pour récupérer l'ID. Donc, quand cet inconvénient est acceptable, très bien.
G.Demecki

@ G.Demecki seriez-vous en mesure de discuter des avantages et des inconvénients de l'utilisation du générateur d'identité hibernate par rapport à cette méthode aller-retour? Serait vraiment utile!
Jordan Mackie

82

Vous devez définir pour Hibernate5.x <property name="hibernate.id.new_generator_mappings">false</property>.. voir et lien .

Pour les anciennes versions d'Hibernate 4.x: <prop key="hibernate.id.new_generator_mappings">false</prop>


où cela est-il ajouté?
Samuel Thompson

1
ajoutez ceci dans les propriétés d'hibernation.
rParvathi


10
Votre réponse pourrait être la solution à la question, mais elle n'explique pas pourquoi elle résout le problème. Veuillez garder à l'esprit que les liens ont tendance à mourir.
Clijsters

51

Travailler avec Spring Boot

Solution

Mettez la chaîne ci-dessous dans .application.properties

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

Explication

Sur Hibernate 4.X, cet attribut est par défaut true.


30

C'est la raison de cette erreur:

Il recherchera comment la base de données que vous utilisez génère des identifiants. Pour MySql ou HSQSL, il existe des champs d'incrémentation qui s'incrémentent automatiquement. Dans Postgres ou Oracle, ils utilisent des tables de séquence. Puisque vous n'avez pas spécifié de nom de table de séquence, il recherchera une table de séquence nommée hibernate_sequence et l'utilisera par défaut. Vous n'avez donc probablement pas une telle table de séquence dans votre base de données et vous obtenez maintenant cette erreur.


1
devrait être marqué comme une réponse car cela explique les choses simplement - bien sûr, un ajout de "spring.jpa.properties.hibernate.id.new_generator_mappings = false" devrait être mentionné mais merci.
nightfury

15

J'obtenais la même erreur "com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: La table 'mylocaldb.hibernate_sequence' n'existe pas".

En utilisant spring mvc 4.3.7 et hibernate version 5.2.9, l'application est faite en utilisant la configuration basée sur spring java. Maintenant, je dois ajouter la hibernate.id.new_generator_mappingspropriété mentionnée par @Eva Mariam dans mon code comme ceci:

@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;
    }

Et cela a fonctionné comme du charme.


14

FYI

Si vous utilisez des fichiers hbm pour définir le mappage O / R.

Remarquerez que:

Dans Hibernate 5, le nom de paramètre du nom de séquence a été modifié .

Le paramètre suivant a bien fonctionné dans Hibernate 4 :

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

Mais dans Hibernate 5 , le même fichier de paramètres de mappage provoquera une erreur "hibernate_sequence does not exist".

Pour corriger cette erreur, le nom du paramètre doit être remplacé par:

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

Ce problème m'a fait perdre 2, 3 heures.

Et d'une manière ou d'une autre, il semble qu'il n'y ait aucun document à ce sujet.

Je dois lire le code source de org.hibernate.id.enhanced.SequenceStyleGenerator pour le comprendre


7

Lorsque vous utilisez

@GeneratedValue(strategy=GenerationType.AUTO)

ou

@GeneratedValue ce qui est un raccourci de ce qui précède, Hibernate commence à décider de la meilleure stratégie de génération pour vous, dans ce cas, il a sélectionné

GenerationType.SEQUENCE comme stratégie et c'est pourquoi il recherche

schemaName.hibernate_sequence qui est une table, pour la génération d'identifiant basée sur une séquence.

Lorsque vous utilisez GenerationType.SEQUENCEcomme stratégie, vous devez fournir les éléments @TableGeneratorsuivants.

     @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;

Lorsque vous définissez la stratégie, il

@GeneratedValue(strategy = GenerationType.IDENTITY) .

Le problème d'origine est résolu car Hibernate cesse de rechercher la table de séquence.


6

Juste au cas où quelqu'un s'arracherait les cheveux avec ce problème comme je l'ai fait aujourd'hui, je ne pourrais pas résoudre cette erreur jusqu'à ce que je change

spring.jpa.hibernate.dll-auto=create

à

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

5

dans hibernate 5.x, vous devez ajouter set hibernate.id.new_generator_mappings à false dans hibernate.cfg.xml

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

2

Vous pouvez également mettre:

@GeneratedValue(strategy = GenerationType.IDENTITY)

Et laissez la DateBase gérer l'incrémentation de la clé primaire:

AUTO_INCREMENT PRIMARY KEY

La réponse ci-dessus m'a aidé.


1

Si vous utilisez la version Hibernate antérieure à Hibernate5 @GeneratedValue(strategy = GenerationType.IDENTITY)fonctionne comme un charme. Mais après Hibernate5, le correctif suivant est nécessaire.

@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

RAISON

Extrait de hibernate-issue

Actuellement, si hibernate.id.new_generator_mappings est défini sur false, @GeneratedValue (strategy = GenerationType.AUTO) est mappé en natif. Si cette propriété est true (qui est la valeur par défaut dans 5.x), la @GeneratedValue (strategy = GenerationType.AUTO) est toujours mappée à SequenceStyleGenerator.

Pour cette raison, sur toute base de données qui ne prend pas en charge les séquences de manière native (par exemple MySQL), nous allons utiliser le générateur TABLE au lieu de IDENTITY.

Cependant, le générateur TABLE, bien que plus portable, utilise une transaction distincte chaque fois qu'une valeur est extraite de la base de données. En fait, même si IDENTITY désactive les mises à jour par lots JDBC et que le générateur TABLE utilise l'optimiseur groupé, l'IDENTITY s'adapte toujours mieux.


0

Cela peut être causé par HHH-10876 qui a été corrigé, alors assurez-vous de mettre à jour vers:

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

1
J'utilise Spring-data-jpa qui utilise en interne Hibernate 5.2.17.Finalcomme implémentation. Je reçois encore cette question quand GenerationTypeest AUTO.
TheCoder

0

J'ai ajouté la séquence Hibernate dans postgres. Exécutez cette requête dans l'éditeur PostGres:

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

Je vais découvrir les avantages / inconvénients de l'utilisation de la requête, mais pour quelqu'un qui a besoin d'aide, vous pouvez l'utiliser.


0

Dans mon cas, le remplacement de toutes les annotations GenerationType.AUTOpar a GenerationType.SEQUENCErésolu le problème.


-2

Exécutez cette requête

create sequence hibernate_sequence start with 1 increment by 1

Demandez-vous de partager les détails sur la façon dont il résout le problème et votre réponse est meilleure que les autres réponses ...
Suraj Kumar
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.