IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

reprise apres erreur


Sujet :

Hibernate Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 543
    Points
    543
    Par défaut reprise apres erreur
    Bonjour, il y quelque chose que je ne comprends pas.

    Je sauve un object avec un champ trop long pour simuler une erreur, oracle me jette et je recoit une exception d hibernate.
    Je fait un rollback et clos la session

    Jusque la tout va bien

    par contre si je corrige mon champs trop long et reesaie de sauver, je prends une StaleObjectStateException :-(
    Si je consulte la base de donnee via sql a la main, elle n a pas changee et le champs version est toujours a la meme valeur!

    Doit on forcement ne plus utiliser l objet acquis par une session precedent une fois que celui ci a genere un probleme dans une session ?

    PS: j utilise hibernate 3.05.5 (c est vieux je sais mais on peut pas avoir mieux car on tourne sur SAP)

  2. #2
    Membre chevronné
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 348
    Points : 1 787
    Points
    1 787
    Par défaut
    Tu peux donner la stack complète ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 543
    Points
    543
    Par défaut les traces en questions
    Voila ce qui se passe:

    1) quand je prends l erreur que j ai intentionnellement generee : (plus de caracteres que possible dans la table). Cette erreur est voulue ;-)
    Hibernate: update USER.VERSIONINFO set VERSION=?, CREATIONDATE=?, AUTHORNAME=?, VERSIONDESC=?, VERSIONGROUP=?, NUMBER=?, CUSTOMERID=? where VERSIONINFOID=? and VERSION=?
    Au sauve cet objet qui est lie a l objet suivant (option « save-update » d hibernate

    Hibernate: update USER.BASICTEST set VERSION=?, VERSIONINFOID=?, BASIC_TEST_DOC_ID=?, THESAURUSID=?, OPERATING_DEPT_ID=?, SUBCATEGORYID=?, CATEGORYID=?, ACCEPTANCE_CRIT=?, TESTSTATUS=?, REQUIREMENTS=?, REF_DOCUMENT=?, TESTINTRO=?, TESTREMARKS=?, USER_UNIQUE_ID=?, USER_NAME=?, IS_IN_TEST_POOL=?, LOCK_BY=?, MASTER=? where TESTID=? and VERSION=?
    10:49:06,128 ERROR JDBCExceptionReporter.java:72) - ORA-12899: valeur trop grosse pour colonne "USER"."BASICTEST"."ACCEPTANCE_CRIT" (actuel: 600, maximum: 500)

    10:49:06,168 ERROR AbstractFlushingEventListener.java:277) - Could not synchronize database state with session
    org.hibernate.exception.GenericJDBCException: could not update: [com.ebs.plus.persistence.Basictest#60]
    at org.hibernate.exception.ErrorCodeConverter.handledNonSpecificException(ErrorCodeConverter.java:92)
    at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:80)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2000)
    at org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1909)
    at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2149)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)

    2) on resauve dans une autre session avec un texte cette fois OK
    Hibernate: update USER.VERSIONINFO set VERSION=?, CREATIONDATE=?, AUTHORNAME=?, VERSIONDESC=?, VERSIONGROUP=?, NUMBER=?, CUSTOMERID=? where VERSIONINFOID=? and VERSION=?
    10:49:06,568 ERROR AbstractFlushingEventListener.java:277) - Could not synchronize database state with session
    org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.ebs.plus.persistence.Versioninfo#59]
    at org.hibernate.persister.entity.BasicEntityPersister.check(BasicEntityPersister.java:1441)
    at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1986)
    at org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1909)
    at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2149)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
    at com.ebs.plus.ejbContainer.services.BasicTestFactoryBean.saveDraftInSavedItem(BasicTestFactoryBean.java:413)
    at com.ebs.plus.ejbContainer.services.BasicTestFactoryBean.saveBasicTest(BasicTestFactoryBean.java:240)
    at test.com.ebs.plus.basicTest.TestBasicTestWithDbUnit.testSaveWithError(TestBasicTestWithDbUnit.java:1518)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    -On voit donc que je prends une exception en essayant de sauver le premier object qui depend de l objet pour lequel j ai appele le save()

    Merci de ton aide

  4. #4
    Membre chevronné
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 348
    Points : 1 787
    Points
    1 787
    Par défaut
    Je n'avais jamais rencontré cette problématique, mais est mon ami

    Jette un oeil à ce post http://forum.hibernate.org/viewtopic.php?t=931005 et surtout à la partie qui parle de l'evict. Je n'ai pas essayé, mais ça me semble être une bonne idée ....

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 543
    Points
    543
    Par défaut solution partielle
    apparement le probleme est reglee dans les dernieres version d hibernate (pas de chance pour moi, je peux pas faire un upgade a cause de pb compatibilite avec SAP)
    cf http://opensource.atlassian.com/proj...browse/HB-1014

    sinon une solution est de mettre les id a null apres avoir fait un evict ou d utiliser un interceptor
    cf http://forum.hibernate.org/viewtopic...ighlight=retry

    j essai et je tiens au courant ...

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 543
    Points
    543
    Par défaut apres essai
    apres avoir fait un essai:

    la solution faire un evict puis mettre l id a null dans le traitement de l exception fonctionne . Je peux alors sauver un nouvel enregistrement dans la table lors de l appel suivant.

    Seul probleme, ca ne marche que pour un NOUVEL enregistrement. si l erreur se produit lors de la sauvegarde d un enregistrement, je peux pas devidement mettre la cle a null (ou alors j en cree un autre).

    Autre pb, mon exception stale object se produit lorsque hibernate sauve un objet lie a l objet que je donne comme argument (cascading). Autrement dit, si je dois modifier mes object en cas d erreur il faut que je sache lesquels ont ete sauvegarde en cascading :-(

    Je pensais que la solution la plus simple c est qu en cas d erreur, le traitement le IHM va simplement considerer que les info de la classe sont KO et ne doivent plus etre utilisees.
    Elle devra recharger un objet avec le meme id

    Seul probleme, ca ne marche pas

    En effet comme l enregistrement a ete je ne sais ou marque comme modifie, il refuse de le reecrire :-(

    Voila le resultat si j essaie:
    Hibernate: update USER.VERSIONINFO set VERSION=?, CREATIONDATE=?, AUTHORNAME=?, VERSIONDESC=?, VERSIONGROUP=?, NUMBER=?, CUSTOMERID=? where VERSIONINFOID=? and VERSION=?
    17:34:40,519 ERROR AbstractFlushingEventListener.java:277) - Could not synchronize database state with session
    org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.ebs.plus.persistence.Versioninfo#59]
    at org.hibernate.persister.entity.BasicEntityPersister.check(BasicEntityPersister.java:1441)
    at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1986)
    at org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1909)
    at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2149)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:324)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)
    at com.ebs.plus.ejbContainer.services.BasicTestFactoryBean.saveDraftInSavedItem(BasicTestFactoryBean.java:413)
    at com.ebs.plus.ejbContainer.services.BasicTestFactoryBean.saveBasicTest(BasicTestFactoryBean.java:240)
    at test.com.ebs.plus.basicTest.TestBasicTestWithDbUnit.testSaveWithError(TestBasicTestWithDbUnit.java:1531)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2007
    Messages : 229
    Points : 543
    Points
    543
    Par défaut solution
    En regardant de plus pres le pb avec le debgugger dans le code d hibernate, j ai trouve la raison du probleme

    le retour du prepared statement . executeUpdate est a 0 (ie aucun enregistrement n a ete modifie) car j essaie la deuxieme fois de modifier un enregistrement qui a pour version=1 mais comme on a fait un rollback, version==0, pas 1 :-(

    Forcement il ne trouve pas l enregistrement et donc me jette.

    Pourquoi le numéro de version n est pas correct :

    J ai 2 tables A et B, A se retrouve avec une fausse version après que la sauvegarde de B ait échoué dans la session (A et B sont sauvées dans la même session)
    Si je fait un save(A) (qui se passe bien) puis un save(B) qui genere le rollback, j ai le problème.
    Le problème ne se produit pas si j utilise le cascade=save-update et non pas une sauvegarde « a la main »

    Conclusion :
    - ne pas faire plusieurs saveOrUpdate() dans une session ou ne pas utiliser la fonctionnalité version dans les tables …

    PS : il semble que dans certains cas hibernate a des pb de gestion des numeros de version en cas de rollback cf http://www.carmanconsulting.com/tapernate/

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Kettle lecture fichier csv reprise après erreur
    Par mario75 dans le forum kettle/PDI
    Réponses: 2
    Dernier message: 23/02/2011, 22h32
  2. [Administration] reprise après basculement sur un réplicat
    Par Celelibi dans le forum Subversion
    Réponses: 1
    Dernier message: 17/05/2008, 12h50
  3. Reprise apres un crash 10G
    Par exempleinfo dans le forum Administration
    Réponses: 11
    Dernier message: 15/05/2008, 12h36
  4. [ DD ] Disque dur introuvable aprés erreur de formatage
    Par DragonHeart dans le forum Composants
    Réponses: 6
    Dernier message: 13/03/2008, 13h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo