-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Optimist Locking en mode détaché
PostPosted: Tue Jan 31, 2006 11:16 am 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
J'essaye d'utiliser le versionnage automatique en mode détaché tel que décrit dans le chapitre 11.3.3.

voir
http://www.hibernate.org/hib_docs/v3/re ... c-detached
http://www.hibernate.org/hib_docs/v3/re ... c-detached

Voici mon problème :
Si je crée une personne, alors ma version est à 0
lors d'une sauvegarde je passe à 1
si je sauve l'objet en version 0, je m'attends à avoir une exception, que je n'ai pas.

En visualisant le SQL, je me rend compte qu'il essaye de modifier une ligne inexistante. Mais je ne sais pas qu'il n'y a pas eu de modification.
update Person set version=1 where name='Gavin' and version=0

J'ai surement du oublier un paramétrage, mais lequel ???

Pour illustrer le cas, j'ai rajouter la méthode de test suivante à la classe
org.hibernate.test.version.VersionTest

Code:
   public void testVersionCRUU() {
      Session s = openSession();
      Transaction t = s.beginTransaction();
      Person gavin = new Person("Gavin");
      s.persist(gavin);
      t.commit();
      s.close();
      
      assertEquals(0, gavin.getVersion());
      Person gavinOld = gavin;
      
      s = openSession();
      t = s.beginTransaction();
      gavin = (Person) s.createCriteria(Person.class).uniqueResult();
      new Thing("Laptop", gavin);
      t.commit();
      s.close();
      
      assertEquals(1, gavin.getVersion());
      
      s = openSession();
      t = s.beginTransaction();
      
      try {
         new Thing("New Laptop", gavinOld);
         
         s.saveOrUpdate(gavinOld);
         
         t.commit();
         
         //Normally fail
         //see DOC chap 11.3.3. Detached objects and automatic versioning
         //http://www.hibernate.org/hib_docs/v3/reference/en/html/transactions.html#transactions-optimistic-detached
         fail("gavingOld must not be save, but it is saved ???? ");
      } catch (Exception e) {
         t.rollback();
      } finally {
         s.close();
      }
      
      s = openSession();
      t = s.beginTransaction();
      s.createQuery("delete from Thing").executeUpdate();
      s.createQuery("delete from Person").executeUpdate();
      t.commit();
      s.close();
   }



Hibernate version:
3.1.2

Name and version of the database you are using:
Oracle 9i

The generated SQL (with p6spy):
Code:
p6spy - 1138719272273|0|0|statement|insert into Person (version, name) values (?, ?)|insert into Person (version, name) values (0, 'Gavin')
p6spy - 1138719272289|0|0|commit||
p6spy - 1138719272398|93|0|statement|select this_.name as name0_0_, this_.version as version0_0_ from Person this_|select this_.name as name0_0_, this_.version as version0_0_ from Person this_
p6spy - 1138719272398|-1||resultset|select this_.name as name0_0_, this_.version as version0_0_ from Person this_|name0_0_ = Gavin, version0_0_ = 0
p6spy - 1138719272414|0|0|statement|select thing_.description, thing_.version as version1_, thing_.longDescription as longDesc3_1_, thing_.person as person1_ from Thing thing_ where thing_.description=?|select thing_.description, thing_.version as version1_, thing_.longDescription as longDesc3_1_, thing_.person as person1_ from Thing thing_ where thing_.description='Laptop'
p6spy - 1138719272430|0|0|statement|insert into Thing (version, longDescription, person, description) values (?, ?, ?, ?)|insert into Thing (version, longDescription, person, description) values (0, '', 'Gavin', 'Laptop')
p6spy - 1138719272430|0|0|statement|update Person set version=? where name=? and version=?|update Person set version=1 where name='Gavin' and version=0
p6spy - 1138719272430|0|0|commit||
p6spy - 1138719272445|15|0|statement|select person_.name, person_.version as version0_ from Person person_ where person_.name=?|select person_.name, person_.version as version0_ from Person person_ where person_.name='Gavin'
p6spy - 1138719272445|0|0|statement|select thing_.description, thing_.version as version1_, thing_.longDescription as longDesc3_1_, thing_.person as person1_ from Thing thing_ where thing_.description=?|select thing_.description, thing_.version as version1_, thing_.longDescription as longDesc3_1_, thing_.person as person1_ from Thing thing_ where thing_.description='New Laptop'
p6spy - 1138719272461|0|0|statement|insert into Thing (version, longDescription, person, description) values (?, ?, ?, ?)|insert into Thing (version, longDescription, person, description) values (0, '', 'Gavin', 'New Laptop')
p6spy - 1138719272461|0|0|statement|update Person set version=? where name=? and version=?|update Person set version=1 where name='Gavin' and version=0
p6spy - 1138719272461|0|0|commit||


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 07, 2006 12:36 pm 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
Même problème pour d'autres personnes
http://forum.hibernate.org/viewtopic.php?p=2290267

J'ai vérifié le paramétrage, et je n'ai pas mieux....


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 1:48 pm 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
Le problème vient d'un bugs JDBC oracle qui lors d'un batch rend -2 au lieu du bon nombre de ligne modifié.
Hibernate ne peut donc pas faire son boulot de vérification des versions. voir :

http://opensource2.atlassian.com/projec ... se/HB-1152
http://forum.hibernate.org/viewtopic.ph ... versionned
http://forum.hibernate.org/viewtopic.ph ... 52#2211752

Je corrige donc mon problème en modifiant la taille des batchs de mon test :
Code:
   protected void configure(Configuration cfg) {
      cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "0");
   }


ou en ajoutant ce même paramétrage sur l'élément class :
Code:
<class name="Person" batch-size="0">


Mais ce n'est pas le mieux, puisque on ne bénéficie plus alors de l'optimisation des batchs. De plus ce problème altére surement le fonctionnement d'hibernate sur d'autres cas.

Il faudrait alors utiliser la propriété hibernate.jdbc.factory_class :
Environment.BATCH_STRATEGY, mais je ne trouve pas un exemple d'implémentation ???

Suite au prochain épisode ;)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 10, 2006 6:21 am 
Regular
Regular

Joined: Tue May 03, 2005 8:19 am
Posts: 53
Location: Paris
En fait il faut utiliser la propriété
Code:
hibernate.jdbc.batch_versioned_data=false


Ce qui permettra aux autres objets de bénéficier du mode batch.

Pour ce qui est du problème du driver JDBC Oracle, il s'avére que -2 est la valeur de la constante Statement.SUCCESS_NO_INFO, voir
http://java.sun.com/j2se/1.4.2/docs/api ... SS_NO_INFO
http://java.sun.com/j2se/1.4.2/docs/api ... SS_NO_INFO

ce n'est donc pas un bug, mais d'après le post suivant, l'utilisation de la classe spécifique du Batch Oracle retourne le nombre de ligne. A voir!
http://forum.hibernate.org/viewtopic.php?p=2211752


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.