-->
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.  [ 6 posts ] 
Author Message
 Post subject: Accès écriture atomique
PostPosted: Thu Mar 20, 2008 5:55 am 
Newbie

Joined: Thu Mar 20, 2008 5:36 am
Posts: 3
Bonjour à tous,
J'ai une petite question, j'ai une application web qui utilise hibernate 3.0 sur du mysql.
J'ai notamment une table USER avec entre autre et par exemple un champ surname.
Est-ce que je peux faire un seul accès atomique pour faire une écriture de ce champ et si oui comment ?

Ou suis-je obligé de faire une requête de lookup pour récupérer l'objet correspondant à mon id, modifier le champ et faire un update ? Ce que je fais déjà mais je trouve ça couteux et j'ai des pbs de verrous et synchro:

Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

User user = null;

String queryString = "select user from User as user where user.id = :idValue";
Query query = session.createQuery(queryString);
query.setString("idValue", id);

for (Iterator it = query.iterate(); it.hasNext();) {
user = (User) it.next();
}

if (user) {
user.setSurname(surname);

session.update(user);

transaction.commit();
session.close();
}


Merci.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 20, 2008 6:55 am 
Beginner
Beginner

Joined: Thu Jan 31, 2008 6:35 am
Posts: 27
Donc oui il faut mieux faire un get et un update.
Plutot comme :
Code:
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

User user = (User) session.get(User.class, id);

if (user) {
user.setSurname(surname);
session.update(user);
}

transaction.commit();
session.close();


En fait il y a une autre solution, que je trouve moins propre, c'est de faire un Update en HQL.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 20, 2008 7:05 am 
Newbie

Joined: Thu Mar 20, 2008 5:36 am
Posts: 3
Merci pour cette réponse rapide.

Quelle est la différence avec la méthode que je proposais ?

Sinon, qu'est-ce qui garantit la synchronisation si par exemple, j'ai en même temps une autre requête qui modifie un autre champ firstname. Le temps du get et du traitement, je peux avoir des incohérences ?

Sinon, tu notes :
User user = (User) session.get(User.class, id);
En fait lorsque je reçois une requête d'un client vers mon AS, j'ai comme paramètre un login qui n'est pas mon id de table.
Commun puis-je passer de ce login à cet id, j'ai besoin de faire un autre lookup ?

Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 20, 2008 10:07 am 
Beginner
Beginner

Joined: Thu Jan 31, 2008 6:35 am
Posts: 27
hibermat wrote:
Quelle est la différence avec la méthode que je proposais ?

C'est plus jolie ! ;)
Non mais faut mieux faire comme ça pour une recherche d'objet par son id (meilleur utilisation du cache de niveau 2)

hibermat wrote:
Sinon, qu'est-ce qui garantit la synchronisation si par exemple, j'ai en même temps une autre requête qui modifie un autre champ firstname. Le temps du get et du traitement, je peux avoir des incohérences ?
Tres bonne question ! :)
Pour des modifs sur deux champs différents, il n'y a aucun problème hibernate ne va updater que les champs modifiés.
(Attention pour savoir si un champ est modifier il utilise la methode equals, donc si tu utilises des UserType, attention de l'avoir bien ecrite)

Apres pour deux écritures sur le meme champs, c'est ton lock policy qui va te permettre de configurer cela. Par defaut on est en lock database (je crois...) c'est à dire que c'est la base de données qui gère la coherence, c'est important surtout dans le cas de cluster avec une base centralisée.
Et la tu as des lock pessimistes, optimiste...

hibermat wrote:
Sinon, tu notes :
User user = (User) session.get(User.class, id);
En fait lorsque je reçois une requête d'un client vers mon AS, j'ai comme paramètre un login qui n'est pas mon id de table.
Commun puis-je passer de ce login à cet id, j'ai besoin de faire un autre lookup ?

La faut faire des Criterias
Code:
       Criteria crit = session.createCriteria(User.class);
       crit.add(Restrictions.eq("login", monLogin));
       crit.setCacheable(true);
       List<User> users = crit.list();
Encore une fois évitez de faire du SQL, on fait de l'objet bordel ! :))


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 20, 2008 10:21 am 
Newbie

Joined: Thu Mar 20, 2008 5:36 am
Posts: 3
sliard wrote:
hibermat wrote:
Sinon, qu'est-ce qui garantit la synchronisation si par exemple, j'ai en même temps une autre requête qui modifie un autre champ firstname. Le temps du get et du traitement, je peux avoir des incohérences ?
Tres bonne question ! :)
Pour des modifs sur deux champs différents, il n'y a aucun problème hibernate ne va updater que les champs modifiés.
(Attention pour savoir si un champ est modifier il utilise la methode equals, donc si tu utilises des UserType, attention de l'avoir bien ecrite)


C'est très intéressant tout ça.
Pour des modifs sur des champs différents, je te garantis que dans mon appli, hibernate s'emmele les pinceaux...
Si j'ai :
- requête 1 met à jour data1 : get user i + set data1
- requête 2 met à jour data2 : get user i + set data2
J'ai parfois les 2 requêtes en même temps et la requête traitée en dernier ne voit pas la modif du premier.
Comment explique tu celà ? J'ai ça avec ce code :
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

User user = null;

String queryString = "select user from User as user where user.id = :idValue";
Query query = session.createQuery(queryString);
query.setString("idValue", id);

for (Iterator it = query.iterate(); it.hasNext();) {
user = (User) it.next();
}

if (user) {
user.setData1(data1);

session.update(user);

transaction.commit();
session.close();
}

Est-ce que l'utilisation de
User user = (User) session.get(User.class, id);
modifie ce comportement ?
A quoi correspond le equals ? As-tu un sample ?
Merci.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 20, 2008 11:09 am 
Beginner
Beginner

Joined: Thu Jan 31, 2008 6:35 am
Posts: 27
hibermat wrote:
Pour des modifs sur des champs différents, je te garantis que dans mon appli, hibernate s'emmele les pinceaux...
Si j'ai :
- requête 1 met à jour data1 : get user i + set data1
- requête 2 met à jour data2 : get user i + set data2
J'ai parfois les 2 requêtes en même temps et la requête traitée en dernier ne voit pas la modif du premier.

Tu travailles dans une transaction, donc les autres threads ne verront pas tes modifs s'ils ont ouvert leur transaction avant que tu n'es fermée la tienne.

Mais si c'est pour updater deux champs différents, je ne vois pas le pb...
En gros la base va voir :
UPDATE USER SET NAME="Toto" WHERE ID=10
UPDATE USER SET FIRSTNAME="Titi" WHERE ID=10

Donc quel que soit l'ordre d'execution le resultat à la fin est le meme.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.