2009-08-14 9 views
3

Je développe une application utilisant Oracle 11g, Java (Struts2) et Hibernate.Problème du générateur de séquence Oracle hibernate

J'ai une table nommée mytemp avec la colonne mytemp_id qui est de type NUMBER (22,0).

Dans mon id fichier mytemp.hbm.xml est telle qu'indiquée ci-dessous

<id name="mytempId" type="big_decimal"> 
     <column name="MYTEMP_ID" precision="22" scale="0" /> 
     <generator class="sequence"> 
      <param name="sequence">MYTEMP_TEMP_ID_SEQ</param> 
     </generator> 
    </id> 

Dans ma séquence de base de données Oracle nommée « MYTEMP_TEMP_ID_SEQ » est créé et fonctionne bien dans Oracle.

Maintenant, lorsque je tente d'insérer l'enregistrement à l'aide mise en veille prolongée, il me donne l'erreur suivante

org.hibernate.id.IdentifierGenerationException: ce générateur id génère long, entier, à court ou chaîne

Il semble en tant que ma séquence renvoie Number, hibenate en la considérant comme BigDecimal, tandis que la classe de générateur de séquençage d'hibernate considère les valeurs qui sont longues, entières, courtes et string uniquement.

Hibernate ne devrait pas avoir de problème avec BigDecimal. Mais je pense qu'ils n'ont pas implémenté BigDecimal pour le générateur de séquence

Quelqu'un peut-il m'aider à résoudre le problème?

Merci.

Répondre

13

Pour être honnête avec vous, je ne peux pas imaginer pourquoi vous insisteriez pour avoir votre ID comme BigDecimal au lieu de long. La valeur longue maximale est 9,223,372,036,854,775,807 qui, bien qu'évidemment est d'environ un millième de la valeur maximale de NUMBER (22), devrait vraiment être assez assez. Si vous deviez générer un million identificateurs chaque seconde, vous auriez à faire cela pour 300 000 ans afin d'épuiser votre séquence. Cela dit, pour que votre identifiant soit généré en BigDecimal, vous devrez écrire votre propre générateur. Vous pouvez le faire en étendant le SequenceGenerator intégré de Hibernate et en remplaçant sa méthode generate(). Au lieu de faire appel à IdentifierGeneratorFactory.get() qui ne supporte que long/int/short/String, vous obtiendrez votre valeur de séquence à partir du jeu de résultats BigDecimal.

Vous aurez alors besoin de declare your generator en spécifiant son nom de classe:

<generator class="com.mypackage.BigDecimalGenerator"> 
    <param name="sequence">MYTEMP_TEMP_ID_SEQ</param> 
</generator> 
+1

Bonjour ChssPly76, Merci pour votre réponse. J'ai converti mon hibernation pour l'utiliser longtemps partout où BigDecimal utilise une séquence en hibernation. Cela résout mon problème. Je l'ai posté ici pour savoir comment puis-je étendre la classe hibernate identifiergenerator pour utiliser bigDecimal pour le générateur de séquences. Je ne comprends pas exactement. Mais la conversion de BigDecimal à long résout problème à coup sûr. Merci. – amar4kintu

+0

J'ai expliqué comment étendre 'SequenceGenerator' dans ma réponse ci-dessus. Jetez un coup d'oeil à sa méthode 'generate()' - vous copieriez tout le contenu et remplaceriez 'IdentifierGeneratorFactory.get()' par 'resultSet.get()' pour obtenir votre valeur 'BigDecimal'. – ChssPly76

+0

J'ai réglé tous mes champs big_decimal pour qu'ils soient considérés comme longs dans mon fichier de génération d'hibernation .. donc ça marche bien maintenant .. merci .. pour votre soutien .. – amar4kintu

2

Avez-vous réglé le bon dialecte? Cela devrait suffire à faire comprendre à Hibernate le résultat de la séquence.

[EDIT] Le problème est que le type de votre séquence ne correspond pas au type de votre colonne. La séquence (selon le message d'erreur d'Hibernate) peut être convertie en long, entier, court ou chaîne tandis que votre séquence renvoie un BigDecimal.

Je suggère de spécifier le type de la colonne ID comme "long" même si Oracle ne connaît pas ce type. En interne, Hibernate devrait être capable de tout projeter correctement pour tout le monde.

+0

oui .. Voici mon dialecte org.hibernate.dialect.Oracle10gDialect amar4kintu

+0

Dans ce cas, le type de votre colonne ID est le problème. Voir mes modifications. –

2

Certainement. Un identifiant long doit être suffisant en considérant toujours le nombre d'enregistrements uniques qu'il peut générer.Le générateur particulier ayant simplement des valeurs spéciales peut être différent du type entier ou avoir le contrôle sur les valeurs de type entier pour une raison quelconque (peut être spécifique au projet).

En outre, le générateur est spécifique à la base de données, comme la séquence pour Oracle, donc la définition de dialact est également importante.

Questions connexes