JPA GenerationType.AUTO pas tenu compte de la colonne avec l'auto-incrément
J'ai une table avec un simple int colonne id de l'Identité incrément automatique dans SQL Server.
L'entité Id est annoté avec @Id
et @GeneratedValue
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", length = 4, precision = 10, nullable = false)
private Integer id;
Dans SQL Server la colonne est correctement défini comme Identité avec Seed
et Increment
est égal à 1.
Quand j'ai essayez de conserver une instance de cette entité, Hibernate tente d'interroger la hibernate_sequence table pour obtenir la valeur de l'ID. Depuis je n'ai pas créé cette table dans mon schéma j'obtiens une erreur:
could not read a hi value: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'MySchema.hibernate_sequence'
Si je change le type de génération de l'IDENTITÉ tout fonctionne comme prévu
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", length = 4, precision = 10, nullable = false)
private Integer id;
Je ne peux pas changer de cette façon, depuis mon Application va fonctionner à la fois sur MS SQL et ORACLE, et ce dernier ne prend pas en charge l'auto incrémenté colonnes.
Autant que je sache, l'AUTO type d'utiliser l'auto incrément de comportement si le sous-jacent de la base de données a l'appui de cela, donc je ne sais pas pourquoi il ne fonctionne pas.
Mise à JOUR:
Il m'a fallu un certain temps, mais j'ai été en mesure de comprendre exactement ce qui se passe.
Je suis en train de travailler avec des bases de données existantes avec les comportements suivants:
- MSSQL: génération de code utilise le tableau de l'IDENTITÉ
- ORACLE: id de génération utilise un déclencheur. Le déclenchement des requêtes et mises à jour une table personnalisée où tous les "à côté id" sont stockés. Ce tableau est appelé SEQ.
Ici est le résultat de l'utilisation de certaines stratégies de génération d'identifiant:
- AUTO: ne fonctionne pas dans MSSQL, comme expliqué ci-dessus
- IDENTITÉ: les travaux MSSQL, mais n'est pas pris en charge par Oracle
- "native": les travaux en MSSQL, mais échoue dans ORACLE. Il échoue parce que Hibernate active par défaut de la séquence de la stratégie, qui utilise hibernate_sequences.nextval. Puisque c'est un héritage de l'application des valeurs de la SEQ tableau (mentionné ci-dessus) et la hibernate_sequences ne sont pas synchronisés (SEQ valeur de cette table est à 6120, et hibernate_sequences " est à 1, ce qui est normal puisque il n'a pas été utilisé jusqu'à présent).
Donc ce que j'ai besoin de trouver un moyen de le configurer de cette entité:
- Utilisation MSSQL Identité fonctionnalité
OU - Lors de l'utilisation d'Oracle, n'a pas automatiquement régler une valeur à la variable ID et de laisser toute la place à la pré-existant déclencher
Cela peut me causer de graves problèmes sur Oracle lorsque j'ai besoin d'insérer des entités qui dépendent de l'entité principale (via clé étrangère), parce que Hibernate n'en connais pas la valeur de l'ID qui a été généré par le "externe" déclencheur.
OriginalL'auteur pipo_dev | 2014-07-30
Vous devez vous connecter pour publier un commentaire.
J'ai eu un problème similaire et j'ai trouvé ce informations (plus profond expliqué dans ici).
L'ajout de cette propriété dans mon persistence.xml fichier de correction de l'émission:
Ce Serveur d'Applications utilisez-vous? Je l'ai testé avec Wildfly-8.2.1.Final
A très bien fonctionné pour moi. Merci. À L'Aide De Wildfly 10
OriginalL'auteur Daniel Rodríguez
Orcale 12c prend en charge l'IDENTITÉ et de SQL SERVER 2012 prend en charge les SÉQUENCES. Je crois qu'un La SÉQUENCE est toujours un meilleur choix qu'une IDENTITÉ. L'IDENTITÉ désactive le traitement par lots et de SÉQUENCES permettent de fournir des optimiseurs, comme le commun-lo stratégie d'optimisation.
Ce qui est du fonctionnement de l'identificateur de générateur est choisi pour le configuré GenerationType valeur:
Si vous utilisez le nouvel identificateur générateurs:
propriétés.put("hibernate.id.new_generator_mappings", "true");
L'AUTO va effectivement utiliser un SequenceStyleGenerator et où la base de données ne prend pas en charge les séquences, vous vous retrouvez à l'aide d'un générateur de tableaux à la place (qui est une solution portable, mais il est moins efficace que celle de l'IDENTITÉ ou de la SÉQUENCE).
Si vous utilisez l'héritage de l'identificateur de générateurs, vous finissent avec "indigènes", la stratégie de génération, qui signifie:
Si une nouvelle Oracle12gDialect va être ajouté et il aura l'appui de votre IDENTITÉ, puis l'AUTO pourrait passer à l'IDENTITÉ plutôt que SÉQUENCE de, risquer de briser vos attentes actuelles. Actuellement, il n'existe pas de tel dialecte disponible donc sur Oracle, vous avez l'ordre et dans MSSQL vous avez IDENTITÉ.
Conclusion:
Essayer comme ça:
Si votre système utilise un tableau pour la génération de la séquence de valeurs et il n'y avait pas de hilo optimisation jamais utilisé, vous pouvez utiliser un identificateur de table générateur:
Vous pouvez également utiliser la JPA générateur de tableaux, assurez-vous de configurer le droit de l'optimiseur. Pour plus d'informations, consultez mon Tutoriel Hibernate
Vérifier mes mises à jour de la réponse, la "Conclusion" de la section.
Il devrait fonctionner sur oracle trop, seulement qu'il sera le hibernate_sequence. Vous ne devriez pas compter sur hbmddl pour l'évolution de votre schéma. Utilisation flywaydb ou liquibase et incrémentale des scripts. De cette façon, vous pouvez personnaliser l'Oracle db séquence bien. Ce générique générateur peut prendre des paramètres, de sorte que vous pouvez personnaliser le nom de schéma pour Oracle trop
Vérifier mes mises à jour de réponse. Vous pouvez définir un générateur de tableaux. Hibernate a beaucoup d'entre eux, à la fois un non hilo héritage, hilo, un multi séquence par la table avec hilo et une nouvelle amélioration d'une prise configurable' optimiseurs.
Vous devez écrire votre propre Hibernate IdentifierGenerator et de passer de l'IDENTITÉ à la TABLE. Si le db ne prend pas en charge identité vous passez à table. Vous pouvez utiliser le GenericGenerator paramètres pour personnaliser votre générateur personnalisé, pour configurer le générateur de tableaux de propriétés. En interne personnalisé de votre générateur pourrait simplement créer une instance de l'héritage de l'identité et de générateur de tableaux et tout simplement déléguer la génération de l'un ou de l'autre, en fonction de votre dialecte en usage.
OriginalL'auteur Vlad Mihalcea
parce que
@GeneratedValue(strategy = GenerationType.AUTO)
utilisation
SequenceStyleGenerator
par défaut dans les versions antérieuresvous avez à regarder ce https://hibernate.atlassian.net/browse/HHH-11014
OriginalL'auteur Muhammad Rfeaat