6
votes

LIQUIBASE: Changez une colonne AT AutoNCremmencrent sur Bigint en utilisant le refactoring ModifyDaTaType avec la base de données H2

J'ai une colonne de clé principale qui est une colonne INT que je voudrais passer à un Bigint. Notre environnement de test et de production utilise MySQL, mais pour les tests d'unité, nous utilisons la base de données H2 intégrée.

J'ai créé le refactoring Liquibase suivant: P>

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;


0 commentaires

3 Réponses :


2
votes

Je changerais d'abord votre @GeneryType à quelque chose de spécifique (comme identité ) pour exclure tout problème avec des valeurs bizarres d'une séquence. Ou retirez-le complètement.

Votre refactoring a l'air bien et je ne vois aucun problème évident.

H2 et Liquibase ne jouent souvent pas ensemble ensemble lorsqu'il s'agit d'identificateurs cités; La classe de base de données H2 à Liquibase cite certaines et ne cite pas d'autres. Peut-être que la conversion de cas vous vissait?

eclipselink a parfois des problèmes lorsqu'un type primitif est 0 (!), car il traitera parfois une telle valeur que null ou non4ialisé, mais à ma connaissance, mais à ma connaissance, mais à ma connaissance souffrir de cette limitation.

Ce n'est pas vraiment une réponse, je sais, mais j'espère que vous devriez vous faire pointer dans la bonne direction.


0 commentaires

6
votes

J'ai testé (hibernate 3.6.2.Final, H2 1.3.160, dialecte: org.hibernate.dialect.h2dialect) Qu'est-ce qui se passe dans votre cas:

  • Lorsque GenerationType est automatique et que le type de données est INT, la génération réelle Type est la séquence.
  • Lorsque GenerationType est automatique et que le type de données est Bigint, réel Type de génération est identité. En conséquence, cela échouera, si le champ ID est défini comme identifiant la clé primaire et non comme identité identité (Ajouter une clé primaire ici avec H2 serait redondant).

    ce que vous pouvez faire:

    Si vous voulez que le type de génération réelle soit séquencer, comme avant, puis xxx

    semble travail. Aucun changement nécessaire pour la séquence elle-même, car Documentation Type est de toute façon de toute façon. Je ferais de cette façon, car alors rien ne change vraiment et il est clair que la séquence de la manière que la séquence de manière générée

    Autre possibilité est de définir la colonne comme identité avec StartValue (en raison de valeurs existantes) et d'utiliser générationtype.auto comme avant de.


3 commentaires

Très bonne analyse - merci. Le seul problème que je vois avec l'utilisation de la séquence est que MySQL ne prend pas en charge les séquences. Une option peut être d'utiliser une table de séquence que nous avons utilisée dans un autre cas.


Bonne idée - L'utilisation de table est la plus portable de toute façon.


Si votre portabilité est votre préoccupation, alors il n'y a essentiellement aucune question: vous devez utiliser @TableGenerator .



2
votes

C'est une ancienne question et la réponse acceptée a une très bonne analyse Mais je suis tombé sur le même problème et j'ai passé 3 heures pour trouver le problème réel et une solution, il vaut donc la quitter ici pour les références futures.

Le vrai problème est donc que sur Liquibase Cette déclaration p> xxx pré>

génère cette requête alter p> xxx pré>

qui supprime la valeur de séquence par défaut de la colonne ID de H2

En conséquence, lorsque vous essayez d'insérer une nouvelle ligne, l'identifiant est NULL, l'erreur SQL est donc lancée. p>

Malheureusement, le comportement de la colonne Alter varie par le fournisseur de base de données. La meilleure solution consisterait à créer différents changelogs de migration pour tester (H2) et production (mysql) p>

et sur h2, vous pouvez effectuer l'identifiant auto_incrènement après la modification de ModifyDaTaType P>

<addAutoIncrement
    columnDataType="bigint"
    columnName="id"
    incrementBy="1"
    startWith="1"
    tableName="event"/>
</changeSet>`


0 commentaires