[JAVA,SQL] NullPointerException bij uitlezen lege DB

Pagina: 1
Acties:

  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
Met een java application ben ik een SQL database aan het uitlezen, het kan in mijn programma voorkomen dat er geen informatie wordt gevonden bij een bepaalde record. Wat het programma dan eigenlijk moet doen is naar het volgende record gaan.

Nu is het probleem dat ik een "java.lang.NullPointerException" krijg omdat er geen informatie kan worden gevonden. Ik denk dat ik een try en catch moet gebruiken maar kan niet echt een goede oplossing vinden.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    protected void executeQuery( Connection con, String sqlStatement )  {

        try {
            Statement s = con.createStatement ( );
            ResultSet rs = s.executeQuery( sqlStatement );          
                
            while ( rs.next ( ) ) {         
                
                if (rs.getObject("Tracks_trackid")== null) {
                    rs.next();
                                                                    
                } else {                    
                    id = ( rs.getObject ("tracks_trackid").toString() );
                    artistsong = ( rs.getObject ("features").toString() );
                }
            }
            rs.close ( );
        }
        
        catch ( SQLException e ) {          
            System.out.println("Error opening the db connection: "+ e.getMessage());
        
        }       
    }

  • RSchellhorn
  • Registratie: Augustus 2001
  • Laatst online: 02-05 20:03
Als je het type van een veld in de database weet, kan je dat beter direct gebruikten, dus in jou geval:
Java:
1
id = rs.getString("Track_ID");


Als het veld dan NULL is, krijg je gelijk een java null terug.

"Ik heb zo veel soep gegeten, dat kan een mens niet aan. Ik heb zo veel soep gegeten, kan bijna niet meer staan. Ik zat daar maar te slurpen achter die grote kop en als ik bijna klaar was, dan schepten ze weer op!" (Hans Teeuwen)


  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
Type van het veld is in ieder geval een INT maar, wat bedoel precies?

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 20:00
Het veld is in de database leeg, er zit niets in. Als je dan je ResultSet probeert uit te lezen ziet Java dat die resultset helemaal leeg, iig dat veld. Je probeert het wel te benanderen dan gooit de javavm er een error tegen aan, dit keer een NullPointerException.

  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
Ja inderdaad, maar hoe los ik dit op? Zie wel oplossing staan zoals hieronder, maar die werken in mijn geval niet.

code:
1
2
3
4
5
6
7
8
9
10
  ResultSet rs;
  ...  
  if (rs.next()) {
     do {
        System.out.println("Record found");
       } while (rs.next());
     }
  else {
     rs.next();
     }


Want hoe kan ik aangeven dat ik naar een volgende record moet. Bij bovenstaande code valt hij op rs.next();

[ Voor 23% gewijzigd door Tha_Spike_1981 op 24-05-2005 08:43 ]


  • RSchellhorn
  • Registratie: Augustus 2001
  • Laatst online: 02-05 20:03
Tha_Spike_1981 schreef op dinsdag 24 mei 2005 @ 08:33:
Type van het veld is in ieder geval een INT maar, wat bedoel precies?
Nauw dat je direct dit kan schrijven:
Java:
1
2
int id = rs.getInt("Track_ID");
if(id == 0) continue; // Was NULL, volgende!


Als het veld in de database NULL is, wordt het id 0. (zie de API specs)

Bovendien als je tracks_trackid een INT is, vind ik deze code nogal vreemd:
Java:
1
id = ( rs.getObject ("tracks_trackid").toString() );

Waarom is id een String hier?

[ Voor 31% gewijzigd door RSchellhorn op 24-05-2005 08:47 ]

"Ik heb zo veel soep gegeten, dat kan een mens niet aan. Ik heb zo veel soep gegeten, kan bijna niet meer staan. Ik zat daar maar te slurpen achter die grote kop en als ik bijna klaar was, dan schepten ze weer op!" (Hans Teeuwen)


  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
Op dit moment zie ik wel dat hij null is (zie vorige post) Wat ik wil is dat hij in de if lus naar een volgende record gaat. Als dat is opgelost dan werkt het.

Inderdaad, dat hoort niet. Het hoort wel een int te zijn. Ben pas sinds kort begonnen met Java dus dat moet ik nog even rechttrekken

[ Voor 30% gewijzigd door Tha_Spike_1981 op 24-05-2005 08:47 ]


  • RSchellhorn
  • Registratie: Augustus 2001
  • Laatst online: 02-05 20:03
Tha_Spike_1981 schreef op dinsdag 24 mei 2005 @ 08:45:
Op dit moment zie ik wel dat hij null is (zie vorige post)
Als je toch alle velden waar in die kolom NULL staat overslaat, waarom laat je je database dat dan niet doen? Dan bedoel ik dus een WHERE kolom NOT NULL.

"Ik heb zo veel soep gegeten, dat kan een mens niet aan. Ik heb zo veel soep gegeten, kan bijna niet meer staan. Ik zat daar maar te slurpen achter die grote kop en als ik bijna klaar was, dan schepten ze weer op!" (Hans Teeuwen)


  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
SQL statement:
code:
1
2
3
4
5
6
7
            db.testDriver();
            db.executeQuery((db.getConnection(host1,db1)), 
                    //"select * from `"+ db1+"`.`trackinfo` where tracks_trackid = "+ song_id);
                    "SELECT * FROM emudb2.trackinfo LEFT OUTER JOIN test.dnpa " +
                    "ON emudb2.trackinfo.tracks_trackid = test.dnpa.Song_id " +
                    "WHERE test.dnpa.Song_id IS NULL " +
                    "AND emudb2.trackinfo.tracks_trackid="+song_id);


Ik kan hier niet een WHERE NOT doen, want ik geeft met een variabele aan dat hij naar dat veld moet, dus ik zal dat moeten afvangen in java.

Hoe kun je simpel naar een volgend record gaan als hij leeg is?

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
je doet

Java:
1
2
if (rs.getObject("Tracks_trackid")== null) {
    rs.next();


dan spring je idd naar het volgende record toe. Maar in je while loop spring je dan nog een keer naar de volgend ( Je else wordt namenlijk niet uitgevoerd ). Je kan dus beter
Java:
1
2
if (rs.getObject("Tracks_trackid")== null) {
    continue;

gebruiken. Hoe je voor de rest kan controleren in java of een veld leeg is weet ik zo even niet uit mijn hoofd.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
rwb schreef op dinsdag 24 mei 2005 @ 09:14:
je doet

Java:
1
2
if (rs.getObject("Tracks_trackid")== null) {
    rs.next();


dan spring je idd naar het volgende record toe. Maar in je while loop spring je dan nog een keer naar de volgend ( Je else wordt namenlijk niet uitgevoerd ). Je kan dus beter
Java:
1
2
if (rs.getObject("Tracks_trackid")== null) {
    continue;

gebruiken. Hoe je voor de rest kan controleren in java of een veld leeg is weet ik zo even niet uit mijn hoofd.
Mijn else wordt wel degelijk uitgevoerd, ik heb er een breakpoint geplaatst en hij roept wel degelijk de else aan. Ik weet al of een veld leeg is maar het gaat er om dat hij naar een volgend veld moet gaan.

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Je kunt toch simpelweg het veld checken? Je moet in elk geval een structurele Null pointer exception altijd kunnen voorkomen.

Maar wat werkt er niet aan je initiele oplossing? Het enige wat ik zo snel zie is dat hij een record extra overslaat.

Maar als je regel 9 t/m 12 vervangt door:
Java:
1
      if ( rs.getObject("Tracks_trackid") != null ) {

dan ben je volgens mij al klaar?
edit:

Begin eerst eens met het juiste type bij het juiste veld te gebruiken. Als id int, gebruik dan getInt() en maak van de variabele dan ook een juiste. Ik neem aan dat features een String is? Gebruik dan getstring om hem uit te vragen.
Bovendien is zoals ik het zie het veld tracks_trackid nooit null, want je vraagt in die query naar een specifiek track_trackid (in je where).
Dus, test je het juiste veld wel op nullwaarde?

edit:

edit 2: En zorg er ook voor dat je je terminologie straight krijgt. Jij zegt dat je naar het volgende veld wil, maar je wil naar het volgende result, ook wel record geheten. Het schept alleen maar verwarring, ook voor jezelf, als je je termen niet goed hanteert.
Ook een puntje om op te letten: globale variabelen vullen vanuit een methode is over het algemeen "not done". Werk of met returnwaarden, of met "by reference" variabelen. Je creeert nu een spaghetti waar je over twee weken niet veel meer mee kan.
Bovendien noem je jouw methode executeQuery, terwijl je hem heel specifiek maar voor 1 soort query kan gebruiken, namelijk 1 die zowel de veldnaam "tracks_trackid" bevat als "features". Je hebt dus een generieke naam bij een specifieke functie.

[ Voor 69% gewijzigd door bigbeng op 24-05-2005 09:36 ]


  • Tha_Spike_1981
  • Registratie: April 2003
  • Laatst online: 24-04 17:59
bigbeng schreef op dinsdag 24 mei 2005 @ 09:24:
Je kunt toch simpelweg het veld checken? Je moet in elk geval een structurele Null pointer exception altijd kunnen voorkomen.

Maar wat werkt er niet aan je initiele oplossing? Het enige wat ik zo snel zie is dat hij een record extra overslaat.

Maar als je regel 9 t/m 12 vervangt door:
Java:
1
      if ( rs.getObject("Tracks_trackid") != null ) {

dan ben je volgens mij al klaar?
Ok, heb ik gedaan maar dan krijg ik nog steeds die "java.lang.NullPointerException" Ik denk dat ik al weet waar het aan ligt, een methode die deze methode aanroept wil ook iets returnen en dan lukt natuurlijk niet.

Mhm, hoe los ik dit nu op?

code:
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
    public static String getMetaData() {
        
        String host1 = "localhost";
        String db1 = "emudb2";
        
        Connector db = new Connector();     
        
        try {
            db.testDriver();
            db.executeQuery((db.getConnection(host1,db1)), 
                    //"select * from `"+ db1+"`.`trackinfo` where tracks_trackid = "+ song_id);
                    "SELECT * FROM emudb2.trackinfo LEFT OUTER JOIN test.dnpa " +
                    "ON emudb2.trackinfo.tracks_trackid = test.dnpa.Song_id " +
                    "WHERE test.dnpa.Song_id IS NULL " +
                    "AND emudb2.trackinfo.tracks_trackid="+song_id);
                
            id = db.id;     
            artistsong = db.artistsong;
            
        } catch (Exception e) {
            
            e.printStackTrace();
        }   
        return artistsong.replaceAll(".txt","");
    }

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Zie ook mijn bijgewerkte vorige reply.

Hoewel dit eigenlijk basic Java programmeren is, en je dus eigenlijk eerst eens wat tutorials zou moeten volgen, of (doe eens gek) een boek lezen, zal ik je toch voorzien van enige tips.

1) Voorkom indien mogelijk exceptions door op de juiste manier te checken, zodat je het gedrag van je applicatie onder controle kunt houden. Je kunt het exception handling systeem wel gebruiken, maar zorg dan eerst dat je deze goed snapt.

2) Gebruik voor het ophalen van data uit de database een entity object, wat je doorgeeft vanuit je datalayer. Bijvoorbeeld:
Song heeft de properties id, title, artist. Je definieert in je datalayer een functie:
Song getSong( int id ); (zelf verder uitwerken)
Je kunt dan zelf bepalen of getSong bij een error een Exception gooit, of een null waarde terug geeft. Persoonlijk zou ik kiezen voor de tweede mogelijkheid, maar goed, dat is een kwestie van smaak.

2a) Als je optie twee doet, implementeer Song dan als een zogeheten Java Bean. Doe eerst even wat research naar wat dat is.

Ik kan zo nog wel even doorgaan, maar ik denk dat als je hier iets mee gaat doen, dat dan alweer meer duidelijk wordt.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Tha_Spike_1981 schreef op dinsdag 24 mei 2005 @ 09:21:
[...]


Mijn else wordt wel degelijk uitgevoerd, ik heb er een breakpoint geplaatst en hij roept wel degelijk de else aan. Ik weet al of een veld leeg is maar het gaat er om dat hij naar een volgend veld moet gaan.
Je else zal idd soms wel aangeroepen worden. Maar ik heb het er over als je veld leeg is dan kom je in de if en daar ga je naar de volgende record toe. De else wordt dan over geslagen want je conditie evalueerde naar true. Dan wordt je While conditie weer gechecked en ga je nogmaals naar de volgende record toe. Zo sla je dus altijd een extra record over als je veld leeg is.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1