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

Java Discussion :

Erreur dans mon ResultSet


Sujet :

Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 124
    Par défaut Erreur dans mon ResultSet
    Bonjour,

    Je travaille actuellement sur un projet pour finaliser une formation. Le truc c'est que je dois réaliser une application en entreprise, mais malheureusement je n'ai aucun tuteur et personne pour m'aider donc pas évident quand on coince sur quelques choses!!!

    Un des points qui m'embête en ce moment, c'est que j'ai fait une requête dans ma BDD et les infos qui me sont retournées je les insères dans un hastable.

    Le souci c'est que vu que mes champs ne sont pas obligatoires, lorsque qu'un d'eux est retourné vide, il me renvoi une erreur: NullPointerException.

    Mais comment faire pour que même si un champs est vide le programme continu.

    Dois-je faire des if et des else ou y a t-il autre chose à faire ?

    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
     
    public Hashtable requeteDetailMateriel() throws SQLException, ClassNotFoundException {
    	String queryAffDetailMateriel;			//Déclaration de la requête
     
    	Hashtable tabDetail = new Hashtable();
     
    	try {
    		//Création de la requête
    		queryAffDetailMateriel  = "SELECT type_interne_materiel, origine_materiel,serie_materiel, date_fabrication_materiel,statut_materiel,date_achat_materiel, nom_marque, statut_mouvement";
    		queryAffDetailMateriel += " FROM materiel mat";
    		queryAffDetailMateriel += " INNER JOIN marque mar";
    		queryAffDetailMateriel += " ON mat.num_marque = mar.num_marque";
    		queryAffDetailMateriel += " LEFT JOIN mouvement mou";
    		queryAffDetailMateriel += " ON mat.num_parc = mou.num_parc";
    		queryAffDetailMateriel += " WHERE mat.num_parc = "+idMateriel;
    		queryAffDetailMateriel += " AND date_debut_mouvement = ";
    		queryAffDetailMateriel += " (SELECT date_debut_mouvement FROM mouvement WHERE num_parc = "+idMateriel+" AND rownum <= 1)";
    		queryAffDetailMateriel += " ORDER BY mat.num_parc";
     
     
    		Class.forName("oracle.jdbc.driver.OracleDriver");
    		sqlc = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE", "gregory", "greg");		     
     
    		//Préparation de la requête avec les données renvoyées par le formulaire d'authentification
    		Statement stm = sqlc.createStatement();
     
     
    		//Execution de la requête
    		ResultSet resAffDetailMateriel = stm.executeQuery(queryAffDetailMateriel);
     
    		while(resAffDetailMateriel.next()) {
    			// Récupération des résultats
    			tabDetail.put("statut_mouvement",this.statut_mouvement);
    			tabDetail.put("type_interne", this.type_interne);
    			tabDetail.put("origine", this.origine);
    			tabDetail.put("nom_marque",this.nom_marque);
    			tabDetail.put("num_serie",this.num_serie);				
    			tabDetail.put("fabrication",this.fabrication);
    			tabDetail.put("statut_materiel",this.statut_materiel);
    			tabDetail.put("date_achat",this.date_achat);
    		}
     
    		//Fermeture du ResultSet
    		resAffDetailMateriel.close();
    		//Fermeture du Statement
    		stm.close();
     
    	} catch (SQLException e) {
    		e.printStackTrace();
    	}
    	return tabDetail;
    }
    Par avance merci

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Par défaut
    Hum tout dépend à quel niveau tu veux gérer ton exception null...


    Au niveau du SGBD ca devrait fonctionner avec un coalesc...

    faire un truc style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    queryAffDetailMateriel  = "SELECT COALESC(type_interne_materiel,'abcd'), COALESC(origine_materiel,'abcd'),...
    Le coalesc te permet de retourner le string abcd si ton paramètre précédent est null.

    aussi-non a la place de directement faire une requête tu peux aussi faire un appel a une fonction et faire la gestion à ce niveau la (ce qui serait probablement le plus propre...).


    Earawyn



    edit : en faisant une fonction tu aurais aussi l'avantage de pouvoir modifier ta requête sans devoir retrifouiller ton code java...

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par roukgreg Voir le message

    Un des points qui m'embête en ce moment, c'est que j'ai fait une requête dans ma BDD et les infos qui me sont retournées je les insères dans un hastable.
    Retourner une hashtable comme ça, c'est mal. Le type et le nom des données est connu à l'avance, alors crée un classe pour contenir ces données plutot ue d'essayer d'utiliser une structure comme hashtable ou hashmap.

    En plus, pour ce que je lit de ton code, ce que tu met dans ta hashtable ne viens même pas de la DB, ca viens de this


    Enfin tu retourne un seul élément alors que ton code est prévu pour plusieurs lignes (cf la boucle sur le resultset). Donc ta méthode devrais avoir la signature:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public List<DetailMateriel> requeteDetailMateriel()

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 124
    Par défaut
    Bonjour,

    Tout d'abord merci pour vos réponses.

    Ensuite earawyn quand tu parles d'une fonction, c'est bien du PL/SQL non? Sinon je ne vois pas trop.

    C'est vrai que ça serait beaucoup plus propre avec, je vais voir, parce que maintenant c'est au niveau du timing que je vais être court . Le temps de me remettre dans le PL et tout...

    Sinon dans un premier temps je peux créer la requête comme ton 1er exemple et revenir aprés si j'ai le temps? Ou je perdrais plus de temps aprés?

    Enfin tchize_ je comprend la création d'un classe en plus, mais en faite j'ai un petit problème de structure de l'application (juste dans ma tête !!! ). En faite je voulais le faire, mais si je fais ça sur chaque modéle de mon projet je vais avoir 50 mille classe. En faite je me demande s'il faut limiter les classes ou si cela se fait souvent de créer plusieurs classes pour une requête.
    Parce qu'en faite j'ai déjà le Modèle, la vue et le controler (d'ou mon problème de pouvoir afficher dans la vue les résultats de mon Modèle, traitées dans mon Controler )

    Encore merci à vous

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par roukgreg Voir le message
    En faite je voulais le faire, mais si je fais ça sur chaque modéle de mon projet je vais avoir 50 mille classe.
    Mmm non, ou alors tu aura 50.000 fonctions comme celle que tu viens de nous montrer et, du coup, au moins 50.000 endroits où tu y fait appel.

    Mon petite doigt me dit qu'on sera plus proche de 5 à 20 classes de résultat différentes

    un hashtable, ce n'est pas structuré. Du coup l'appelant peux tenter de lire avec une faute, ou attendre des champs qui n'existeront jamais, ou se tromper de type ou .... Et tout ça tu ne pourra jamais le voir à la compilation, c'est toujours en prod que ça te pêtera à la figure. D'où l'intérêt d'être strict sur tes structure de retour.

    Je ne dis pas que la HasMap n'est pas utile (par exemple quand tu ne connais pas à l'avance la requête), mais ici tout est connu à l'avance.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 124
    Par défaut
    Ok je te remercie pour tes précisions.

    Juste une dernière petite question pour être bien clair dans ma tête, lorsque je crée ma méthode avec ma requête, je renvoi tout dans une classe qui me permettra de récupérer mes infos, mais est-ce qu'avec cette solution il me faut faire une fonction pour vérifier si les champs son null ou pas? ou est-ce que je traite ce cas dans ma nouvelle classe?

    En faite j'essai juste de faire les choses proprement mais un peu de mal. c'est vrai que si j'avais voulu j'aurais pu faire un peu à "l'arrache" et mettre tout ca dans le même fichier(requête, traitement et affichage), mais je voulais faire ça le plus propre et structuré possible.

    En tout cas merci de tes réponses

  7. #7
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par roukgreg Voir le message
    Ok je te remercie pour tes précisions.

    Juste une dernière petite question pour être bien clair dans ma tête, lorsque je crée ma méthode avec ma requête, je renvoi tout dans une classe qui me permettra de récupérer mes infos, mais est-ce qu'avec cette solution il me faut faire une fonction pour vérifier si les champs son null ou pas? ou est-ce que je traite ce cas dans ma nouvelle classe?
    Tu n'aura aucun soucis, c'est hashtable qui refuse les valeurs null, pas ta classe. Donc pas de hashtable, pas de soucis, tu laisse l'appelant gérer les null quand il les lits dans ta classe.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2012
    Messages : 4
    Par défaut
    Oui oui roukreg, je parlais bien d'une fonction PL/SQL... Maintenant si tu ne connais pas c'est assez simple...

    Voici un code que t'aurais juste a modifier un peu :

    Au niveau de ta BDD tu aurais :
    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
     
    create or replace
    FUNCTION MaFct (MonParam1 integer, MonParam2 integer)  RETURN CURSEUR.C1 IS
     
    MyCURSOR CURSEUR.C1;
     
    begin
      OPEN MyCURSOR FOR select ...
    		from ...
    		WHERE ... 
    		ORDER BY ...;
     
     
    RETURN MyCURSOR;
     
    END MaFct;
    Au niveau du java tu aurais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Class.forName("oracle.jdbc.driver.OracleDriver");
    con= DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE", "gregory", "greg");
     
    String query = "begin ? := MaFct(?,?); end;";
    CallableStatement statement = con.prepareCall(query);
    statement.registerOutParameter(1,OracleTypes.CURSOR);
     
    statement.setString(2,MonParam1);
    statement.setString(3,MonParam2);
     
    statement.executeQuery();
     
    ResultSet rs = (ResultSet)statement.getObject(1);


    Si tu veux garder le principe de hashtable, avec les COALESC ca marchera niquel vu que aucune valeur null ne sera retournée...
    Maintenant il est vrai que créer une classe en fonction de ton résultat serait mieux. Ca rejoint le principe des Java entity... Si tu as le temps n'hésite pas a creuser le sujet.



    Earawyn

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 124
    Par défaut
    Bonjour,

    Mon prof est venu me rendre visite hier, il m'a conseillé ton idée tchize_, car beaucoup plus rapide. En revanche j'ai fait ça directement dans mon modèle parce que je ne maitrise pas trop les manager de table. J'avoue que maintenant je vais essayer de faire ça bien, mais je dois également prendre en compte le temps.

    Mais il m'a dit aussi qu'une trés bonne application doit aussi avoir un traitement au niveau de la BDD, fonction, procédure, triggers, mais pour l'instant ne pas trop me concentrer dessus, car une nouvelle fois, pas trop de temps

    Je bûche pas mal, je suis très fatigué!!! , mais ce n'est pas décourageant pour l'instant.

    Voici comment j'ai fait pour ceux que ça intéresse au cas ou :
    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
    public void requeteDetailMateriel() throws SQLException, ClassNotFoundException {
    	String queryAffDetailMateriel;			//Déclaration de la requête
     
    	try {
    		//Création de la requête
    		queryAffDetailMateriel  = "SELECT type_interne_materiel, origine_materiel,serie_materiel, date_fabrication_materiel,statut_materiel,date_achat_materiel, nom_marque, statut_mouvement";
    		queryAffDetailMateriel += " FROM materiel mat";
    		queryAffDetailMateriel += " INNER JOIN marque mar";
    		queryAffDetailMateriel += " ON mat.num_marque = mar.num_marque";
    		queryAffDetailMateriel += " LEFT JOIN mouvement mou";
    		queryAffDetailMateriel += " ON mat.num_parc = mou.num_parc";
    		queryAffDetailMateriel += " WHERE mat.num_parc = "+idMateriel;
    		queryAffDetailMateriel += " AND date_debut_mouvement = ";
    		queryAffDetailMateriel += " (SELECT date_debut_mouvement FROM mouvement WHERE num_parc = "+idMateriel+" AND rownum <= 1)";
    		queryAffDetailMateriel += " ORDER BY mat.num_parc";
     
     
    		//Préparation de la requête avec les données renvoyées par le formulaire d'authentification
    		Statement stm = sqlc.createStatement();
     
     
    		//Execution de la requête
    		ResultSet resDetMat = stm.executeQuery(queryAffDetailMateriel);
     
    		while(resDetMat.next()) {
    			this.setStatut_mouvement(resDetMat.getInt("statut_mouvement"));
    			this.setType_interne(resDetMat.getString("type_interne_materiel"));
    			this.setOrigine(resDetMat.getString("origine_materiel"));
    			this.setNom_marque(resDetMat.getString("nom_marque"));
    			this.setNum_serie(resDetMat.getString("serie_materiel"));
    			this.setFabrication(resDetMat.getDate("date_fabrication_materiel"));
    			this.setStatut_materiel(resDetMat.getInt("statut_materiel"));
    			this.setDate_achat(resDetMat.getDate("date_achat_materiel"));		
    		}
     
    		//Fermeture du ResultSet
    		resDetMat.close();
    		//Fermeture du Statement
    		stm.close();
     
    	} catch (SQLException e) {
    		e.printStackTrace();
    	}
    }
    Voilà. Maintenant que j'arrive à afficher tout mes résultat je pense garder cette méthode pour la suite.

    Pour cette partie problème résolu, maintenant je m'attaque au JButton dans une JTable, j'espère que ce va le faire.

    En tout les cas un grand merci pour vos réponses, ça m'a bien aidé

  10. #10
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Citation Envoyé par roukgreg Voir le message
    Voilà. Maintenant que j'arrive à afficher tout mes résultat je pense garder cette méthode pour la suite.
    Ce code ne me semble pas correct. L'appel à this.setXXX laisse entendre que tu positionne des variables de ta classe mais lors de l'appel à ces fonctions, s'il y a plusieurs lignes, tu risques vas ecraser les valeurs précédentes. Bien sur, il y a peut etre un hashtable/list qui est utilisé dans ces fonctions mais ce serait moche et le nom de la fonction ne serait pas adapté.

    En fait, il faudrait plutot faire un truc du genre (bien sur, tu peux passer les donnees en private avec les get/set qui vont bien mais l'idée est la) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class MesDonnees {
      public int d1;
      public String d2;
      public MesDonnees()
      {
      }
    }
    Puis, dans ta fonction requeteDetailMateriel, un truc du genre :
    public List<MesDonnees> requeteDetailMateriel() throws SQLException, ClassNotFoundException {
    ...
    List<MesDonnees> list = new ArrayList<MesDonnees>();
    while(resDetMat.next()) {
    MesDonnees donnee = new MesDonnees();
    donnee.d1 = resDetMat.getInt("statut_mouvement");
    donnee.d2 = resDetMat.getString("type_interne_materiel");
    list.add(donnee);
    }

    return list;
    }


    Citation Envoyé par roukgreg Voir le message
    Pour cette partie problème résolu, maintenant je m'attaque au JButton dans une JTable, j'espère que ce va le faire.
    Bon courage, c'est pas le plus simple. Mais une piste : regarde du coté des CellRenderer

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

Discussions similaires

  1. (urgent) Erreur dans mon select à cause du NOT IN
    Par MoTUmBo dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 29/11/2005, 20h28
  2. Fonction qui renvoie erreur dans mon état
    Par Daniel MOREAU dans le forum Access
    Réponses: 1
    Dernier message: 20/10/2005, 12h40
  3. erreur dans mon script
    Par Swata dans le forum Langage
    Réponses: 4
    Dernier message: 21/09/2005, 00h02
  4. [langage]erreur dans mon script
    Par Fabouney dans le forum Langage
    Réponses: 11
    Dernier message: 30/06/2005, 14h58
  5. [Lien]erreur dans mon programme python
    Par durnambule dans le forum Général Python
    Réponses: 11
    Dernier message: 29/01/2004, 14h59

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