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 :

Hibernate et les transactions [Hibernate2]


Sujet :

Hibernate Java

  1. #1
    Membre actif
    Avatar de didate
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Guinée

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 90
    Points : 238
    Points
    238
    Par défaut Hibernate et les transactions
    Bonjour

    Je suis entrain de faire une mini auto formation en Hibernate, j'arrive à faire des opérations CAUD.

    Par contre j'ai un souci avec la gestion des transactions, je n'arrive pas à desactiver l'autocommit sur la connexion. Le programme commit les mise à jours avant même que je ne fasse transaction.commit();

    Le code Java

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
     
    // Récupération d'une session Hibernate
            Session s = HibernateUtils.getSession();
     
            // Début de la transaction
            Transaction t = s.beginTransaction();
     
            t.begin();
     
            // Création d'un objet Event
            Event e = new Event();
            e.setTitle("Titre de l'event 1");
            e.setDescription("Description de l'évènement 1");
            e.setBeginDate(new GregorianCalendar());
            e.setAllDay(false);
            //Cette instruction commit déjà les maj
            s.save(e);
     
            // J'aimerai que le commit se passe ici
            t.commit();
     
            // Fermeture de la session Hibernate
            s.close();
    Le fichier Hibernate.cfg.xml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                             "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
     <session-factory name="">
      <!--  Paramètres de connexion à la base de données -->
      <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
      <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="hibernate.connection.url">jdbc:mysql://localhost/pge_jpa_v1</property>
      <property name="hibernate.connection.username">root</property>
      <property name="hibernate.connection.password"/>
      <!-- Comportement pour la conservation des tables -->
      <property name="hbm2ddl.auto">create</property>
      <property name="hibernate.hbm2ddl.auto">update</property>
      <property name="hibernate.connection.autocommit">false</property>
      <!-- Fichiers à mapper -->
      <mapping class="fr.mistra.pgejpav1.jpa.Event"/>
      <!-- Affiche les logs SQL 
            <property name="show_sql">true</property> 
            <property name="hibernate.format_sql">true</property> 
            <property name="use_sql_comments">true</property> -->
     </session-factory>
    </hibernate-configuration>
    Je travail avec une base de données MySql

    Merci d'avance
    L'effort fait les forts

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Que fait la classe HibernateUtils ?
    Peux-tu montrer son code ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre actif
    Avatar de didate
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Guinée

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 90
    Points : 238
    Points
    238
    Par défaut
    la voici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
     
    package fr.mistra.pgejpav1.utils;
     
    import java.io.File;
     
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.AnnotationConfiguration;
     
    public class HibernateUtils {
        private static final SessionFactory sessionFactory;
     
        // Crée une unique instance de la SessionFactory à partir de hibernate.cfg.xml
        static {
            try {
                sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
            } catch (HibernateException ex) {
                throw new RuntimeException("Problème de configuration : " + ex.getMessage(), ex);
            }
        }
     
        // Renvoie une session Hibernate
        public static Session getSession() throws HibernateException {
        		return sessionFactory.openSession();
        }
    }
    L'effort fait les forts

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Ok, je voulais être sûr que tu ne modifiais pas l'auto-commit dans cette méthode...

    En théorie, c'est bien le paramétrage <property name="hibernate.connection.autocommit">false</property> qui permet de désactiver l'auto-commit.
    Il y a une chose dans ton fichier de paramétrage qui m'interpelle, c'est le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <session-factory name="">
    ... Peux-tu essayer en mettant un nom ?

    Une autre chose, il faut bien sûr que tu ais créé une base "innoDB" dans MySQL...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre actif
    Avatar de didate
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Guinée

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 90
    Points : 238
    Points
    238
    Par défaut
    Merci pour la réponse.

    J'ai ajouter un nom la session-factory. La base de données est belle et bien de type "innoDB".

    J'ai toujours le même résultat...

    je vais essayer avec un autre SGBD pour voir ce que ça donne ...
    L'effort fait les forts

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    J'ai utilisé MySQL assez souvent et je n'ai jamais eu ce problème, par contre, j'utilise un autre driver
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre actif
    Avatar de didate
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Guinée

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 90
    Points : 238
    Points
    238
    Par défaut
    Finalement ça à marcher

    J'avais fais une mauvaise manip,la table "event" n'était pas en "InnoDB" contrairement aux autres (faute d’inattention ?, le weekend ? chepa)...


    Merci à toi OButterlin...

    J'aimerai avoir ton avis (critiques et suggestions) sur la classe ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
     
    import org.hibernate.Session;
    import org.hibernate.Transaction;
     
    public class SessionManager {
     
    	private Transaction transaction;
    	private Session session;
     
    	/**
             * Permet de persister un object en base
             * @param e : l'object à persister
             */
    	public void save(Object e){
    		getSession();
    		getTransaction();
    		session.save(e);
    	}
     
    	/**
             * Permet de persister un object en base
             * @param e : l'object à persister
             * @param doCommit : permet de savoir si un commit doit-être fait ou pas
             */
    	public void save(Object e, boolean doCommit){
    		this.save(e);
    		if(doCommit) transaction.commit();
    	}
     
    	/**
             * Obtient une transaction
             * @return
             */
    	public Transaction getTransaction() {
    		if(transaction==null || !transaction.isActive()) {
    			transaction = getSession().beginTransaction();
    		}
    		return transaction;
    	}
    	/**
             * Obtient une session
             * @return
             */
    	public Session getSession() {
    		if(session==null || !session.isOpen())
    			session=HibernateUtils.getSession();
    		return session;
    	}
     
    	/**
             * Commit une transaction
             */
    	public void doCommit(){
    		if(transaction!=null && transaction.isActive())
    			transaction.commit();
    	}
    }
    L'effort fait les forts

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Tu devrais jeter un oeil sur le pattern DAO, c'est plutôt intéressant et très utilisé.

    Pour ce qui est de ta classe, elle s'occupe plus particulièrement de la session et de la transaction, ce qui est pas mal en soit, mais à l'usage, tu seras vite limité.
    En gros, tu devrais avoir une classe utilitaire pour l'acquisition d'une session et sa libération.
    Ensuite une classe typée DAO qui va s'occuper de l'aspect CRUD (Create, Read, Update, Delete) sur un object lié à la DB.
    Cet objet DAO va utiliser la classe utilitaire pour acquérir une session s'il n'en possède pas déjà une. Ce dernier point est important quand tu voudras créer un objet unique d'interface entre ton application et la DB, on parle généralement de "façade", un autre pattern intéressant, surtout dans le monde des EJB.
    En gros, ton application voit la façade, la façade s'occupe de faire le lien avec n DAO en fonction des besoins et si tu dois faire une modification sur n tables mais dans la même transaction, il faut évidement partager la session...
    Un exemple pour illustrer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    class DAOClient
    {
        private Session session;
     
        public Session getSession()
        {
            if (session == null)
            {
                this.session = HibernateUtils.getSession();
            }
            return this.session;
        }
        public void setSession(Session session)
        {
            this.session = session;
        }
    ...
    }
    class DAOAdresse
    {
        private Session session;
     
        public Session getSession()
        {
            if (session == null)
            {
                this.session = HibernateUtils.getSession();
            }
            return this.session;
        }
        public void setSession(Session session)
        {
            this.session = session;
        }
    ...
    }
     
    class MonApplicationFacade
    {
        public Client saveClient(Client client)
        {
            Session session = HibernateUtils.getSession();
            DAOClient clientDAO = new DAOClient();
            clientDAO.setSession(session);
            DAOAdresse adresseDAO = new DAOAdresse();
            adresseDAO.setSession(session);
     
            clientDAO.save(client);
            adresseDAO.save(client.adresse);
     
        }
    }
    Bon, c'est un exemple, juste pour illustrer, en pratique, on passerait plutôt par un singleton pour les DAO.
    Voilà, j'espère que ça t'aidera un peu
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre actif
    Avatar de didate
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2010
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Guinée

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2010
    Messages : 90
    Points : 238
    Points
    238
    Par défaut
    Oui c'est vrai, la classe SessionManager ne fait que centralisé la gestion des sessions et transaction.

    Pour le pattern DAO, je l'utilisais sans le savoir . Avec ce pattern on peut par exemple passer facilement de JDBC à Hibernate ou bien d'un SGBD à un fichier XML.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
     package fr.dvp.dao;
     
     
    public abstract class PatternDAOContrat<T> {
     
    	/**
             * Permet de récupérer un objet via son ID
             * @param id
             * @return
             */
    	public abstract T find(long id);
     
    	/**
             * Permet de créer une entrée dans la base de données
             * par rapport à un objet
             * @param obj
             */
    	public abstract void add(T obj);
     
    	/**
             * Permet de mettre à jour les données d'une entrée dans la base 
             * @param obj
             */
    	public abstract void update(T obj);
     
    	/**
             * Permet la suppression d'une entrée de la base
             * @param obj
             */
    	public abstract void delete(T obj);
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    package fr.dvp.dao;
     
    import fr.dvp.entity.Event;
    import fr.dvp.hiber.SessionManager;
     
    public class EventDAO extends PatternDAOContrat<Event> {
     
    	@Override
    	public Event find(long id) {
    		// TODO Auto-generated method stub
    		return null;
    	}
     
     
     
    	@Override
    	public void delete(Event obj) {
    		// TODO Auto-generated method stub
     
    	}
     
     
     
    	@Override
    	public void add(Event obj) {
    		SessionManager s = new SessionManager();
    		s.save(obj,true);
     
    	}
     
     
     
    	@Override
    	public void update(Event obj) {
    		// TODO Auto-generated method stub
     
    	}
     
    }
    Dans mes recherches sur ce pattern j'ai découvert un autre qui est aussi très intéressant, le pattern Factory, qui permet de centraliser la création des instances des DAO (partternDAO).

    Si je me libère un peu pendant la journée, je vais voir ce que me propose le pattern façade.
    L'effort fait les forts

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

Discussions similaires

  1. JSF et les Transactions hibernate
    Par mobuho dans le forum JSF
    Réponses: 4
    Dernier message: 01/03/2012, 13h54
  2. Réponses: 4
    Dernier message: 06/09/2005, 09h58
  3. petite aide sur les transactions et triggers SVP
    Par CharleLéo dans le forum Débuter
    Réponses: 4
    Dernier message: 15/11/2004, 20h43
  4. les Transactions sous interbase
    Par kouraichi35 dans le forum Bases de données
    Réponses: 2
    Dernier message: 20/10/2004, 11h15
  5. [interbase] gerer les transactions
    Par webbulls dans le forum Bases de données
    Réponses: 3
    Dernier message: 14/05/2004, 18h27

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