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

Persistance des données Java Discussion :

"nullPointer exception", je trouve pas l'erreur [Débutant(e)]


Sujet :

Persistance des données Java

  1. #1
    Membre du Club
    Homme Profil pro
    graphisme & impression
    Inscrit en
    Mars 2011
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : graphisme & impression

    Informations forums :
    Inscription : Mars 2011
    Messages : 118
    Points : 69
    Points
    69
    Par défaut "nullPointer exception", je trouve pas l'erreur
    Bonjour,

    Je suis entrain de faire ma première application en Java et j'ai une erreur que je ne comprends pas! Enfin j'ai compris que l'objet était null quelque part mais je comprends pas où!

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at servicescrud.AccesBDD.newTransaction(AccesBDD.java:58)
    at servicesFonctionnels.ServicesFonctionnelsPatient.memoriser(ServicesFonctionnelsPatient.java:15)
    at controler.ControlerPatient.controle(ControlerPatient.java:18)

    L'application est composé comme ça:
    Vue
    Controler
    Modele (avec les services d'appel à la base de données)
    Singelton AccesBDD pour l'entityManager.


    Je suis débutant donc désolé si quelque chose vous parait pas très pro.
    Merci beaucoup pour votre aide.
    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
     
    package controler;
     
    import toolbox.Message;
    import entites.Patient;
    import model.Model;
     
    public class ControlerPatient extends AbstractControler{
     
     
    	public ControlerPatient(Model pModel){
    		super(pModel);
    	}
     
     
    	public Boolean controle(Patient pPatient) {
    		Boolean controle = false;
    		if(pPatient.getPrenom() != null){
    			this.model.getSfPatient().memoriser(pPatient);
    			System.out.println(Message.getStatut());
    		}
    		return controle;
    	}
     
     
     
    }
     
    package model;
     
    import java.util.Date;
     
    import servicesFonctionnels.IServicesFonctionnels;
    import servicesFonctionnels.ServicesFonctionnelsConsultation;
    import servicesFonctionnels.ServicesFonctionnelsPatient;
     
    import entites.Consultation;
    import entites.Therapeute;
     
    public class Model extends AbstractModel{
     
     
    	private ServicesFonctionnelsPatient sfPatient;
     
    	public Model(){
    		super();
    		this.sfPatient = new ServicesFonctionnelsPatient();
    	}
     
    	public ServicesFonctionnelsPatient getSfPatient() {
    		return sfPatient;
    	}
     
    	public void setSfPatient(ServicesFonctionnelsPatient sfPatient) {
    		this.sfPatient = sfPatient;
    	}
     
     
     
     
    }
     
    package servicesFonctionnels;
     
     
    import servicescrud.AccesBDD;
    import servicesunitaires.ServicesUnitairesPatient;
    import toolbox.Message;
    import entites.Patient;
     
    public class ServicesFonctionnelsPatient implements IServicesFonctionnels<Patient>{
     
    	private static ServicesUnitairesPatient suPatient = new ServicesUnitairesPatient();
    	private static AccesBDD singelton = AccesBDD.getInstance();
     
    	public void memoriser(Patient pPatient) {
    		singelton.newTransaction();
    		suPatient.creer(pPatient);
    		Message.setStatut(Message.TypeStatut.objetMemorise);
    		singelton.endTransaction();
    	}
     
    	public Patient editer(Patient pPatient) {
    		singelton.newTransaction();
    		Patient patientRecherche = suPatient.valider(pPatient);
    		if(Message.getStatut() == Message.TypeStatut.objetValide){
    			Message.setStatut(Message.TypeStatut.objetEdite);
    		}
    		singelton.endTransaction();
    		return patientRecherche;
    	}
     
    	public void modifier(Patient pPatient) {
    		singelton.newTransaction();
    		if(Message.getStatut() == Message.TypeStatut.objetEdite){
    			suPatient.mettreAjour(pPatient);
    			Message.setStatut(Message.TypeStatut.objetModifie);
    		}
    		singelton.endTransaction();
    	}
     
    	public void efface(Patient pPatient) {
    		singelton.newTransaction();
    		Patient patientRecherche = suPatient.valider(pPatient);
    		if(Message.getStatut() == Message.TypeStatut.objetValide){
    			suPatient.supprimer(patientRecherche);
    			Message.setStatut(Message.TypeStatut.objetEfface);
    		}
    		singelton.endTransaction();
    	}
     
     
     
    }
     
     
    package servicescrud;
     
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Persistence;
     
    public class AccesBDD {
     
    	public static final String NOM_UNIT = "jpa";
     
    	private static AccesBDD singleton = null;
     
    	private EntityManagerFactory emf;
     
    	private EntityManager em;
     
    	private EntityTransaction transaction;
     
    	private AccesBDD(){
    		try{
    			this.emf = Persistence.createEntityManagerFactory(NOM_UNIT);
    			this.em = emf.createEntityManager();
    		} catch (Exception e) {
    			throw new RuntimeException("Connexion impossible... Verifier le serveur de BDD et le fichier persistence.xml up :"+NOM_UNIT+e.getMessage());
    		}
    	}
     
    	public static AccesBDD getInstance() {
    		if (singleton == null){
    			singleton = new AccesBDD();
    		}
    		return singleton;
    	}
     
    	public EntityManager getEntityManager(){
    		return this.em;
    	}
     
     
    	public void deconnecte() throws Exception{
    		if (emf != null){
    			emf.close();
    			emf = null;
    		}
    		if (em != null){
    			em.close(); 
    			em = null;
    		}
    	}
     
     
    	public void endTransaction() {
    		this.transaction.commit();
    	}
     
    	public void newTransaction() {
    		this.transaction = this.em.getTransaction();
    		this.transaction.begin();
    	}
     
    }

  2. #2
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Points : 15 059
    Points
    15 059
    Par défaut
    Bonsoir,

    Tu as un NullPointerException, c'est que tu utilises un variable non instancié (avec un new ou par injection) à la ligne 58 de la classe AccesBDD.java.

    Peut-on voir le code de cette classe?

    A+.

  3. #3
    Membre du Club
    Homme Profil pro
    graphisme & impression
    Inscrit en
    Mars 2011
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : graphisme & impression

    Informations forums :
    Inscription : Mars 2011
    Messages : 118
    Points : 69
    Points
    69
    Par défaut merci
    Coucou,

    Merci pour ta réponse… J'ai compris qu'il s'agit d'une variable non-instancié*…
    En fait, je suppose que mon problème vient de la class AccesBDD mais je comprends pas pourquoi… Mon but c'est de faire un singelton avec cet class car l'entity manager doit être déclarer une seule fois d'après ce que j'ai compris…

    Par contre je comprends pas pourquoi il est null car je l'appel toujours via getInstance qui initialise les deux variables*…

    Merci beaucoup pour votre aide

    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
    59
    60
    61
    62
    63
    64
     
     
    package servicescrud;
     
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Persistence;
     
    public class AccesBDD {
     
    	public static final String NOM_UNIT = "jpa";
     
    	private static AccesBDD singleton = null;
     
    	private EntityManagerFactory emf;
     
    	private EntityManager em;
     
    	private EntityTransaction transaction;
     
    	private AccesBDD(){
    		try{
    			this.emf = Persistence.createEntityManagerFactory(NOM_UNIT);
    			this.em = emf.createEntityManager();
    		} catch (Exception e) {
    			throw new RuntimeException("Connexion impossible... Verifier le serveur de BDD et le fichier persistence.xml up :"+NOM_UNIT+e.getMessage());
    		}
    	}
     
    	public static AccesBDD getInstance() {
    		if (singleton == null){
    			singleton = new AccesBDD();
    		}
    		return singleton;
    	}
     
    	public EntityManager getEntityManager(){
    		return this.em;
    	}
     
     
    	public void deconnecte() throws Exception{
    		if (emf != null){
    			emf.close();
    			emf = null;
    		}
    		if (em != null){
    			em.close(); 
    			em = null;
    		}
    	}
     
     
    	public void endTransaction() {
    		this.transaction.commit();
    	}
     
    	public void newTransaction() {
    		this.transaction = this.em.getTransaction();
    		this.transaction.begin();
    	}
     
    }

  4. #4
    Membre du Club
    Homme Profil pro
    graphisme & impression
    Inscrit en
    Mars 2011
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : graphisme & impression

    Informations forums :
    Inscription : Mars 2011
    Messages : 118
    Points : 69
    Points
    69
    Par défaut une idée
    Bonjour,

    Personne n'a une idée? Je comprends pas ma faute car pour moi le singleton garanti que mon instance n'est pas null…

    Merci

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 37
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    L'exception indique que ton objet EntityManager de ta classe AccesBDD est null lors de l'exécution de la méthode newTransaction.

    A première vue, il semble que ton singleton soit bien initialisé. Donc ta variable doit être mise à null après la création du singleton. Je vois que ta méthode deconnecte fait cela. Tu dois donc avoir un appel qui est fait à cette méthode.

    Tu peux vérifier cela en posant des points d'arrêts en debug.

  6. #6
    Membre du Club
    Homme Profil pro
    graphisme & impression
    Inscrit en
    Mars 2011
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : graphisme & impression

    Informations forums :
    Inscription : Mars 2011
    Messages : 118
    Points : 69
    Points
    69
    Par défaut merci
    Hello,

    Merci infiniment, c'était bien cela!
    Merci beaucoup, bonne journée

  7. #7
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2006
    Messages : 70
    Points : 218
    Points
    218
    Par défaut
    Attention toutefois, le même bug peut survenir à cause de l'environnement mutli-thread induit par l'utilisation d'AWT.

    En effet, même si tu n'as pas créer explicitement de threads, ton application est bien et bien multi-threadé.
    En atteste l'exception générée: "Exception in thread "AWT-EventQueue-0"
    Il s'agit, du thread qui gère les évènements de ton interface graphique.

    Or, AccesBDD étant un singleton, ta classe est accessible aussi bien par le thread principal (l'appel à static void main(...) ), qu'au thread d'affichage (méthode paint() et companie) et au thread des évènements de l'interface.

    De fait, ta classe doit être thread-safe, ce qui n'est pas le cas.
    Et le même problème peut survenir de pointeur null peut survenir !
    En effet, ton entityManager est créé à l'instanciation de la classe AccesBDD.

    Les problèmes pouvant survenir sont les suivants:
    -deux appels à la méthode statique getInstance() peuvent instancier deux fois l'objet (il suffit que les deux threads arrivent à la condition "singleton == null" en même temps).
    - l'instance a bien été construire une seule fois, mais les différents threads ne sont pas au courant de la bonne "publication" d'une variable (ex: un thread peut voir em à null, et un autre instancié).
    - plusieurs thread tentent de faire des opérations en base de données en même temps (et je ne suis pas sur que les transactions soient thread-safe).



    Pour ce qui est de la "publication" d'une variable, il faut comprendre que chaque thread travail avec sa propre mémoire. Celle-ci doit alors être synchronisée avec la mémoire centrale pour "lire" la valeur réelle de certaines variables, ou pour "écrire". Sans celà, on peut lire des valeurs obsolète, ou encore écrire une valeur qui ne sera jamais mise à jour.
    La synchronisation ne peut être "forcée" que par des block synchronized, ou par l'appel de méthode lock() et unlock() d'un objet implémentant l'interface Lock.

    (Je prends beaucoup de raccourcis, le sujet est vase, je te laisses juste quelques pistes pour faire des recherches plus approfondies).


    Le problème peut être le suivant:
    Ton instance a été initialisé dans le thread principal, celui-ci possède toutes les variables "à jour".
    Le thread d'évènement récupère l'instance, mais pour lui, les attributs sont toujours à null, car la synchronisation de la mémoire n'a pas été faite. Tu as donc un pointeur null. Alors que ce n'est normalement le cas, EntityManager a bien été crée, mais le thread d'évènement n'est tout simpelment pas au courant...





    Pour solutionner ton problème, il te faut en premier remédier à la bonne initialisation du singleton.


    private static final AccesBDD singleton = new AccesBDD();

    voir: http://christophej.developpez.com/tu...n/multithread/



    Tu peux remarquer l'ajout du mot clef "final". Celui ci interdit la réaffectation de la variable. Ca a son intérêt dans un environnement multi-thread, puisque celà permet à la JVM de faire des optimisations sur son modèle mémoire.

    En effet, la variable ne pouvant pas prendre d'autres valeurs, on s'assure de sa bonne publication, et donc de sa bonne visibilité par les autres threads. Il n'est pas nécéssaire dans ce cas de faire de synchronisation.

    Pour résumer:
    - soit tu utilises le mot clef "final" sur un attribut
    - soit il faut synchroniser l'affectation de l'attribut pour s'assurer de sa bonne visibilité aux autres threads.



    Il reste le fait de t'assurer que deux threads ne puissent pas exécuter de transaction en même temps. Ce que permet ta classe en l'état actuel.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 10/08/2006, 13h44
  2. [Sécurité] boucle infinie je trouve pas l'erreur
    Par scorpking dans le forum Langage
    Réponses: 14
    Dernier message: 26/07/2006, 15h04
  3. je ne trouve pas l'erreur ?
    Par nourdine dans le forum Langage
    Réponses: 7
    Dernier message: 04/01/2006, 23h51

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