mon entité clé primaire ressemble ci-dessous
@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;
quand je cours, je reçois une erreur
impossible d'obtenir ou de mettre à jour la valeur suivante; l'exception imbriquée est org.hibernate.exception.SQLGrammerException: impossible d'obtenir ou de mettre à jour la valeur suivante
mais quand je change
@GeneratedValue
private Long id;
pas de jet d'erreur. Je veux générer une clé primaire unique par table sur Oracle db.
La @GeneratedValue(strategy=GenerationType.TABLE)
indique au fournisseur JPA d'utiliser une table pour obtenir des ID lors de l'insertion d'entités nouvellement créées dans la base de données.
Lorsque vous utilisez Hibernate comme fournisseur, cela se traduira par une table hibernate_sequences
qui comporte deux colonnes: le nom de l'entité et l'identité max déjà attribuée à cette entité. Ici, il semble qu'Hibernate ne réussisse pas à obtenir le prochain ID de celui-ci pour votre entité, mais il est difficile de dire exactement pourquoi, car vous n'avez pas fourni suffisamment d'informations pour cela.
Alors, pourriez-vous s'il vous plaît fournir le stacktrace complet? Veuillez également activer la journalisation avec hibernate.show_sql
propriété définie sur true
et définissez le niveau de journal approprié log4j.logger.org.hibernate.SQL=DEBUG
. Joignez le journal à votre question si possible.
Peut-être vérifiez simplement que vous avez bien configuré le hibernate.dialect
pour Oracle. En fait, joignez aussi votre configuration de mise en veille prolongée si possible.
PS: La façon "traditionnelle" de générer PK avec Oracle est d'utiliser des séquences (vous pouvez laisser Hibernate deviner la meilleure stratégie pour votre type de base de données en utilisant GenerationType.AUTO
ou le forcer en utilisant SEQUENCE
) mais je suppose que vous voulez que la structure de données résultante soit indépendante de la base de données. Sinon, je suggérerais plutôt de choisir des séquences.
EDIT: Répondre à un commentaire du PO sur GenerationType.AUTO
. En effet, la valeur par défaut est une seule séquence globale appelée hibernate_sequence
et cela pourrait être un problème. Mais, avec la configuration ci-dessous, vous pouvez utiliser GenerationType.AUTO
et contrôle toujours le nom de la séquence pour les cas où la base de données utilise des séquences:
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;
En d'autres termes, vous pouvez utiliser un nom de séquence différent pour chaque table sans perdre la portabilité.
Il existe 4 stratégies pour la génération automatique dans JPA:
Pour l'annotation de clé primaire de génération automatique Oracle, Sequence et Table sont vos choix. La logique de base consiste à définir d'abord un générateur, utilisez @ SequenceGenerator ou @ TableGenerator respectivement, puis utilisez le générateur comme attribut dans @ GeneratedValue .
Voici un exemple d'utilisation de la stratégie de séquence:
@Id
@SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
private long id;
Voici un exemple d'utilisation de la stratégie de table:
@Id
@TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1 )
@GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN")
private long id;
Si aucun générateur n'est spécifié dans l'annotation @ GeneratedValue , le choix sera laissé à l'implémentation JPA.
Si vous travaillez sur une base de données avec des tables existantes, assurez-vous que la séquence ou la table définie dans la base de données avant d'exécuter votre application. Le générateur de table aura également besoin que vous insériez une ligne dans la table avant que l'annotation @GeneratedValue puisse fonctionner correctement.
Voici un tutoriel sur comment configurer la génération automatique de clé primaire dans la base de données JPA pour Oracle .