Partage
  • Partager sur Facebook
  • Partager sur Twitter

Hibernate 3.5

Gestion des exceptions

    7 février 2013 à 18:24:36

    Bonjour à tous,

    Je me permets de demander de l'aide sur un point qui, malgré mes recherches, reste très flou.

    Je développe actuellement une application java (swing) qui utilise 2 bases de données Mysql (une locale (esclave) et une distante (maître) hébergée sur un serveur). Les 2 bases ayant le même schéma, j'utilise donc Hibernate 3.5 pour effectuer mes requêtes.

    Toutefois, je bloque sur la gestion des diverses exceptions générées par Hibernate, ou pas MySQL...

    - Comment ne pas faire cracher l'application en cas d'erreur de ce genre, que faut-il catcher et à quel endroit ?

    - Comment vérifier que la connexion est toujours là lorsque je souhaite faire une requête ? Faut-il vérifier avant chaque requête ?

    - Comment gérer l'exception dans le cas où le service MySQL est désactivé ?

    - Comment gérer l'exception dans le cas où les identifiants sont erronés ?

    Lorsque je provoque volontairement (ou pas ^^) ces différents cas, j'ai des erreurs telles que :

    807 [AWT-EventQueue-0] WARN org.hibernate.cfg.SettingsFactory - Could not obtain connection metadata

    com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

    java.net.SocketException

    MESSAGE: java.net.ConnectException: Connection refused

    Mais je ne sais absolument pas comment gérer ce genre de chose :(

    Pour information, j'utilise une classe HibernateUtils (code ci-après) qui me créé des instances uniques sur chacune de mes SessionFactory (locale + distante).

    public class HibernateUtils {
    
    	private static Logger logger = Logger.getLogger(HibernateUtils.class);
    
    	private static SessionFactory sessionFactoryLocale = null;
    	private static SessionFactory sessionFactoryMaster = null;
    
    	private static boolean connecteLocal;
    	private static boolean connecteMaster;
    
    	private HibernateUtils(){
    		;
    	}
    
    	public static void deconnectionLocale() {
    		HibernateUtils.getInstanceLocale().close();
    		sessionFactoryLocale.close();
    	}
    
    	public static void deconnectionMaster() {
    		HibernateUtils.getInstanceMaster().close();
    		sessionFactoryMaster.close();
    	}
    
    
    	public static Session getInstanceLocale() {
    		connecteLocal = true;
    		if (sessionFactoryLocale == null) { // Premier appel
    			try {
    
    				Configuration configurationLocale = new Configuration();
    				configurationLocale.configure("hibernateLocal.cfg.xml");
    
    				try {
    					InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("hibernateLocal.properties");
    					Properties propertiesLocales = new Properties();
    					propertiesLocales.load(is);
    					//propertiesLocales.load(new FileReader("./hibernateLocal.properties"));
    					configurationLocale.addProperties(propertiesLocales);
    				} catch (Exception e) {
    					connecteLocal = false;
    					logger.fatal("Erreur lecture fichier properties Locales" + e.toString());
    				}
    
    				try {
    					sessionFactoryLocale = configurationLocale.buildSessionFactory();
    				} catch (HibernateException e) {
    					//TODO
    					logger.fatal("getInstanceLocale" + e.getMessage());
    					//throw new DataAccessLayerException(e);
    				}
    			} catch (Throwable ex) {
    				connecteLocal = false;
    				logger.fatal("Erreur creation de la SessionFactory" + ex.toString());
    			}
    		}
    		
    		Session test = null;
    		
    		try {
    			test = sessionFactoryLocale.openSession();
    		} catch(HibernateException e) {
    			logger.fatal("OUVERTURE SESSION IMPOSSIBLE");
    		}
    		
    		return test;
    	}
    
    	public static Session getInstanceMaster() {
    		setConnecteMaster(true);
    		if (sessionFactoryMaster == null) { // Premier appel
    			try {
    
    				Configuration configurationMaster = new Configuration();
    				configurationMaster.configure("hibernateMaster.cfg.xml");
    
    				try {
    					InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("src/hibernateMaster.properties");
    					Properties propertiesMaster = new Properties();
    					propertiesMaster.load(is);
    					//propertiesMaster.load(new FileReader("src/hibernateMaster.properties"));
    					configurationMaster.addProperties(propertiesMaster);
    				} catch (Exception e) {
    					setConnecteMaster(false);
    					System.out.println("Erreur lecture fichier properties Master" + e.toString());
    				}
    
    				try {
    					sessionFactoryMaster = configurationMaster.buildSessionFactory();
    				} catch (HibernateException e) {
    					//TODO
    					System.out.println("getInstanceMaster" + e.getMessage());
    					//throw new DataAccessLayerException(e);
    				}
    
    			} catch (Throwable ex) {
    				setConnecteMaster(false);
    				System.out.println("Erreur creation de la SessionFactory" + ex.toString());
    			}
    		}
    		return sessionFactoryMaster.openSession();
    	}
    
    
    	public static boolean isConnecteLocal() {
    		return connecteLocal;
    	}
    
    	public static void setConnecteLocal(boolean connecteLocal) {
    		HibernateUtils.connecteLocal = connecteLocal;
    	}
    
    	public static boolean isConnecteMaster() {
    		return connecteMaster;
    	}
    
    	public static void setConnecteMaster(boolean connecteMaster) {
    		HibernateUtils.connecteMaster = connecteMaster;
    	}
    
    	public static void rollback(Transaction tx) {
    		try {
    			if (tx != null) {
    				tx.rollback();
    			}
    		} catch (HibernateException ignored) {
    			logger.error("Couldn't rollback Transaction", ignored);
    		}
    	}
    }


    Merci de votre aide,

    A bientôt !!

    • Partager sur Facebook
    • Partager sur Twitter
      9 février 2013 à 14:43:39

      Si tu crées un client lourd, il ne faut pas utiliser Hibernate parce que ton programme sera décompilable.

      Bien sur si c'est juste pour s'entrainer ou dans un but éducatif, pas de souci.

      Ton appli elle fonctionne en local ? Ou c'est lorsque tu tentes de te connecter à distance ?

      • Partager sur Facebook
      • Partager sur Twitter
      Site : https://gokan-ekinci.appspot.com | Miagiste en recherche d'emploi | Profil [Dév. Java SE & EE | Dév. QlikView]
        9 février 2013 à 16:41:47

        Bonjour,

        C'est bien une petite application java (swing) en local à but "éducatif". Mais cette application utilise 2 bases de données. La première est en local, afin que chacun puisse utiliser l'application indépendamment de toute connexion internet. La seconde base, que j'appelle la Master, est la base sur laquelle je réplique les modifications faites sur la base locale dès qu'un utilisateur de l'application est connecté au net. Elle est hébergée sur un serveur sécurisé.

        Mais ma question porte d'avantage sur les problèmes "basiques" :

        - Comment vérifier que la connexion avec la base est toujours là quand je fais une requête ?! J'essaye de faire des try catch, j'en ai mis plein mais ça ne catch rien du tout !!

        Je veux juste sécuriser le fonctionnement. Quand par exemple je désactive le service mysql, l'appli crache bien comme il faut. Comment traiter ce cas en affichant juste une pop up dans l'application demandant à l'utilisateur de vérifier ses paramètres ?

        Merci pour votre aide.

        • Partager sur Facebook
        • Partager sur Twitter
          12 février 2013 à 21:22:12

          Gugelhupf a écrit:

          Si tu crées un client lourd, il ne faut pas utiliser Hibernate parce que ton programme sera décompilable.

          C'est quoi cette ineptie ????? Si tu veux décompiler du java, tu peux le faire hibernate ou pas. Bon, je dois être creuvé... Non, en fait, je suis creuvé, je relirais ça demain voir si mes yeux ne m'ont pas joué des tours.

          Valentin37, je pense que tu peux faire cela en utilisant un interceptor et en particulier grace à la méthode afterTransactionCompletion

          Tu trouveras de la doc sur le net pour ce que tu cherches à faire. Je sais plus trop comment on les déclare mais tu devrais trouvé facilement ton bonheur. C'est exactement ce qui est utilisé par envers pour faire du versionning si ça peut t'aider ;)

          • Partager sur Facebook
          • Partager sur Twitter
            13 février 2013 à 13:25:11

            Bonjour patouche,

            Merci de ta réponse.

            Toutefois, sais-tu comment je pourrais catcher l'erreur de création de la session ?! J'ai vu rapidement sur internet le pool de connexion c3p0, mais je n'ai pas tout compris (notamment dans les paramètres).

            Peut-on l'utiliser pour une application java ? Est ce que cela permet de catcher plus d'exceptions concernant les problèmes de connexion ? (Erreur de création de la sessionFactory, erreur d'ouverture de la session ...) ?

            Je n'arrive pas à remonter d'exception quand je coupe (volontairement) le service mySql en plein pendant l'exécution de mon application.

            • Partager sur Facebook
            • Partager sur Twitter
              14 février 2013 à 0:45:34

              oui, tu peux très bien utilisé hibernate dans une application client lourd. Ca ne change rien. Je le fait même à chaque fois que j'ai besoin d'une database sur un projet. ta datasource, ton driver jdbc, ... et roule !!

              Pour ce que tu demande, je ne sais pas trop. En fait, quand je fais du client lourd, j'utilise quand même spring et donc, sans connection, l'appli vautre lamentablement au démarrage. Je pense cependant que cela doit être possible mais je sais pas trop comment. Après, c'est pas top non plus de chercher à catcher une runtime mais tu peux toujours regarder commnent ça marche si tu ouvres toi même ta connexion à la main.

              Après si l'exception ne remonte pas, ça ne m'étonne pas trop lorsque tu coupe l'accès à la db. Pour comment le faire, je ne sais pas du tout comment mais après avoir un peu chercher, tu peux peut être utilisé un ConnectionObserver que tu rajoutes à ton LogicalConnectionImplementor

              Bref, bon courage dans tes recherches...

              • Partager sur Facebook
              • Partager sur Twitter

              Hibernate 3.5

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown