|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Membre à l'essai
![]() graphisme & impression Inscription : mars 2011 Messages : 72 ![]() |
Bonjour,
Je suis entrain de faire ma première application en Java 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 :
|
||
|
|
00
|
|
|
#2 |
![]() ![]() Andry Aimé Inscription : septembre 2007 Messages : 6 368 ![]() |
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+. |
|
|
00
|
|
|
#3 | ||
|
Membre à l'essai
![]() graphisme & impression Inscription : mars 2011 Messages : 72 ![]() |
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 :
|
||
|
|
00
|
|
|
#4 |
|
Membre à l'essai
![]() graphisme & impression Inscription : mars 2011 Messages : 72 ![]() |
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 |
|
|
00
|
|
|
#5 |
|
Candidat au titre de Membre du Club
![]() Inscription : novembre 2006 Messages : 37 ![]() |
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. |
|
|
00
|
|
|
#6 |
|
Membre à l'essai
![]() graphisme & impression Inscription : mars 2011 Messages : 72 ![]() |
Hello,
Merci infiniment, c'était bien cela! Merci beaucoup, bonne journée |
|
|
00
|
|
|
#7 |
|
Candidat au titre de Membre du Club
![]() Inscription : février 2006 Messages : 8 ![]() |
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. |
|
|
00
|
Copyright © 2000-2013 - www.developpez.com