# Daten in MySQL-Datenbank schreiben



## derFabi95 (26. Mai 2016)

Hallo zusammen!
Ich schreibe momentan ein Plugin für Minecraft. Da sollen (per Befehl) Daten in eine Datenbank geschrieben (und ausgelesen) werden. Die Verbindung zur Datenbank passt, die läuft, und die Table wird erstellt.. Allerdings kann ich nicht in die Datenbank inserten.
Das wäre die Fehlermeldung:


Spoiler: Error-Code





```
[Server thread/ERROR]: Error occurred while enabling PetitionPlugin v0.1 (Is it up to date?)
java.lang.NullPointerException
    at me.John_H_Smith.Main.MySQL.update(MySQL.java:49) ~[?:?]
    at me.John_H_Smith.Main.Main.ConnectMySQL(Main.java:39) ~[?:?]
    at me.John_H_Smith.Main.Main.onEnable(Main.java:21) ~[?:?]
    at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:292) ~[spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at org.bukkit.craftbukkit.v1_9_R1.CraftServer.loadPlugin(CraftServer.java:361) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at org.bukkit.craftbukkit.v1_9_R1.CraftServer.enablePlugins(CraftServer.java:321) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at net.minecraft.server.v1_9_R1.MinecraftServer.t(MinecraftServer.java:411) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at net.minecraft.server.v1_9_R1.MinecraftServer.l(MinecraftServer.java:376) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at net.minecraft.server.v1_9_R1.MinecraftServer.a(MinecraftServer.java:331) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at net.minecraft.server.v1_9_R1.DedicatedServer.init(DedicatedServer.java:269) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:527) [spigot_server.jar:git-Spigot-e6f93f4-d884ab3]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
```




Hier mal mein Code:


Spoiler: Main.java





```
package me.xxx.Main;

import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;

import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

public class Main extends JavaPlugin {
    public Logger log = this.getLogger();
   
    @Override
    public void onEnable() {
        this.getCommand("petition").setExecutor(new COMMAND_petitionplugin());
       
        initConfig();
        ConnectMySQL();
    }
   
    @Override
    public void onDisable() {
        CloseMySQL();
    }
   
    public static MySQL mysql;
   
   
    public void ConnectMySQL() {
        String dhost = this.getConfig().getString("PetitionPlugin.mysql.host");
        String duser = this.getConfig().getString("PetitionPlugin.mysql.user");
        String ddatabase = this.getConfig().getString("PetitionPlugin.mysql.database");
        String dpassword = this.getConfig().getString("PetitionPlugin.mysql.password");
        mysql = new MySQL(dhost, ddatabase, duser, dpassword);
        mysql.update("CREATE TABLE IF NOT EXISTS PEs (id INT(20) AUTO_INCREMENT, Name varchar(20), Message varchar(30), CoordsX double(9,6) SIGNED, CoordsY double(9,6) SIGNED, CoordsZ double(9,6) SIGNED, primary key (id))");
    }
   
    public void CloseMySQL() {
        mysql.close();
    }
   
    private void initConfig() {
        this.reloadConfig();
        this.getConfig().options().header("Mach mal was da drin");
        this.getConfig().addDefault("PetitionPlugin.mysql.host", "localhost");
        this.getConfig().addDefault("PetitionPlugin.mysql.database", "database");
        this.getConfig().addDefault("PetitionPlugin.mysql.user", "user");
        this.getConfig().addDefault("PetitionPlugin.mysql.password", "password");
        this.getConfig().options().copyDefaults(true);
        this.saveConfig();
    }

}
```






Spoiler: COMMAND_petitionplugin.java





```
package me.xxx.Main;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class COMMAND_petitionplugin implements CommandExecutor {

    public static MySQL mysql;
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label,
            String[] args) {      
       
        if(cmd.getName().equalsIgnoreCase("petition")) {
            Player player = (Player) sender;
           
            mysql.update("INSERT INTO PEs(Name,Message) VALUES (Test1,Test2)");
            return true;
        }
        return false;
    }
}
```






Spoiler: MySQL.java





```
package me.xxx.Main;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MySQL {
   
    private String HOST = "";
    private String DATABASE = "";
    private String USER = "";
    private String PASSWORD = "";
   
    private Connection con;
   
    public MySQL(String host, String database, String user, String password) {
        this.HOST = host;
        this.DATABASE = database;
        this.USER = user;
        this.PASSWORD = password;
       
        connect();
    }
   
    public void connect() {
        try {
                con = DriverManager.getConnection("jdbc:mysql://" + HOST + ":3306/"
                      + DATABASE + "?autoReconnect=true", USER, PASSWORD);
                System.out.println("[PE] Datenbank verbunden!");
        } catch (SQLException e) {
            System.out.println("[PE] Verbindung Fehlgeschlagen! Grund: " + e.getMessage());
        }
    }
   
    public void close() {
        try {
            if (con != null) {
                con.close();
                System.out.println("[PE] Datenbank geschlossen!");
            }
        } catch (SQLException e) {
            System.out.println("[PE] Verbindung schließen fehlgeschlagen! Grund: " + e.getMessage());
        }
    }
   
    public void update(String qry) {
        try {
                Statement st = con.createStatement();
                st.executeUpdate(qry);
                st.close();
        } catch (SQLException e) {
            connect();
            System.err.println(e);
        }
    }
   
    public boolean hasConnection() {
        if(con != null) {
            return true;
        }
        return false;
    }
   
    public ResultSet query(String qry) {
        ResultSet rs = null;
        try {
                Statement st = con.createStatement();
                rs = st.executeQuery(qry);
        } catch (SQLException e) {
            connect();
            System.err.println(e);
        }
        return rs;
    }
}
```




Wieso geht in der COMMAND_petitionplugin.java das 
	
	
	
	





```
mysql.update("INSERT INTO PEs(Name,Message) VALUES (Test1,Test2)");
```
 nicht?
Eclipse zeigt mir keine Fehler an.


----------



## X5-599 (27. Mai 2016)

Warum das in der COMMAND_petitionplugin.java nicht funktioniert kann ich dir sagen: Du deklarierst ein zweites statisches MySQL Objekt, aber initialisierst es nicht.

Allerdings scheint mir das nicht das Problem zu sein. Der Stacktrace lässt vermuten, dass der Fehler bereits auftritt wenn die ConnectMySQL() Methode ausgeführt wird. Diese initialisiert das (erste) statische MySQL objekt und ruft dann darauf update() auf.
Wenn die MySQL Klasse, die du gepostet hast genauso bei dir aussieht (also nicht irgendwo andere/leere Zeilen existieren), dann kommt dein Fehler daher, dass das Connection objekt (con) null ist. Die verursachende Zeile wäre dann: "Statement st = con.createStatement();"
Das kann in diesem Fall nur heissen, dass DriverManager.getConnection() eine Exception geworfen hat und darum das Connection objekt nicht initialisieren konnte. Du müsstest also irgendwo auch dein System.out "Verbindung fehlgeschlagen" sehen können.
Was mich verwirrt, denn du sagst ja dass die Verbindung steht und auch eine Tabelle erzeugt wird... Der Stacktrace lässt aber anderes vermuten. Es sei denn es ist ein alter, der mit deinem Problem nichts zu tun hat. Mir ist z.b. auch nicht klar warum du vermutest, dass es an der Klasse:COMMAND_petitionplugin.java liegt. Die wird in dem Stacktrace nicht erwähnt. Wenn es also tatsächlich an der Klasse COMMAND_petitionplugin.java liegen sollte ... dann siehe meinen Hinweis im ersten Satz dieses Postes.


----------



## derFabi95 (27. Mai 2016)

Aber wieso hat es dann in der Main.java auch funktioniert ohne dass ich die Variable initialisiert habe?
Und ja: die Verbindung wird aufgebaut. Dazu muss ich sagen, ich bin noch recht blutiger Anfänger in Java, bin aber der Meinung, Übung macht den Meister. Insofern das ganze bitte "Anfänger-Freundlich" erklären.

Achja, es muss an der Klasse COMMAND_petitionplugin.java liegen, da eben dieses insert nur aufgerufen wird, wenn man einen Befehl eingibt. Sofern der Befehl nicht ausgeführt wird, wird auch kein Versuch unternommen, mysql.update() auszuführen. Und nur dann kommt diese Fehlermeldung


----------



## X5-599 (27. Mai 2016)

Ich kenne mich mit Minecraft leider nicht aus und weiss auch nicht wie dessen Plugin System funktioniert. Aber der Stacktrace, den du gepostet hast sagt, dass der Fehler nicht in der Klasse COMMAND_petitionplugin liegt.

```
at me.John_H_Smith.Main.MySQL.update(MySQL.java:49) ~[?:?]
    at me.John_H_Smith.Main.Main.ConnectMySQL(Main.java:39) ~[?:?]
    at me.John_H_Smith.Main.Main.onEnable(Main.java:21) ~[?:?]
```

Die erste Zeile gibt die Stelle an, an der der Fehler auftrat. Die folgenden Zeilen sind die Stellen im Code, die vorher ausgeführt wurden. Also hier:
wird ausgeführt zuerst:
Die Methode onEnable() in der Klasse Main
 gefolgt von:
Der Methode ConnectMySQL() in der Klasse Main
 gefolgt von:
Der Methode update() in der Klasse MySQL

da ist keine Rede von der Klasse COMMAND_petitionplugin. Schwierig von hier aus den Fehler einzugrenzen. Ist das ganze reproduzierbar? Also, kommt jedesmal beim Ausführen der gleiche Stacktrace (den, den gepostet hast)?


----------



## derFabi95 (27. Mai 2016)

Naja, das im Log ist ja klar. Er ruft, wenn ich mysql.update("insert blabla...") ausführe, die public void update in der MySQL.java aus, von der aus im onEnable die Verbindung aufgebaut . Was ich halt nicht verstehe, ist die Tatsache, dass es in der Main.java funktioniert und in der COMMAND_petitionplugin.java nicht. Bin momentan leider noch in der Arbeit, werde aber heute Abend wenn ich zuhause bin die Logs nochmal überprüfen, sollten aber die gleichen sein. Achja, auch mit mysql.query("insert blabla...") funktioniert es nicht, was ja klar ist, da es in der MySQL.java als ResultSet angegeben wird.


----------



## mrBrown (27. Mai 2016)

Was funktioniert denn in der Main? Der Stacktrace oben ist doch ein Aufruf aus der Main - das funktioniert also nicht.

In der COMMAND_petitionplugin kann es nicht funktionieren, weil du dein MySQL nie initialisiert, du versuchst also immer auf null zuzugreifen.


----------



## derFabi95 (27. Mai 2016)

In der Main verbindet er ja erfolgreich zur Datenbank, und erstellt ggf die neue Table. Und das ja auch, ohne dass mysql initialisiert ist. Oder?

Edit: ah nein, er initialisiert mit new... 
Wie wende ich das dann an, indem er das ganze bei Befehl macht? Muss ich da wieder eine neue Verbindung aufbauen lassen?


----------



## mrBrown (27. Mai 2016)

Das ginge zB, indem du deinem COMMAND_petitionplugin das in der Main erstellte MySQL übergibst


----------



## derFabi95 (27. Mai 2016)

Tut mir leid dass ich jetzt so blöd fragen muss: wie? Bisher hab ich sowas noch nie gemacht. Ich verstehe, DASS das gemacht werden muss und auch warum, aber nicht ganz wie. Kleiner Denkanstoß, durch den ich evtl per Google drauf komm?


----------



## mrBrown (27. Mai 2016)

Konstruktor mit Parametern benutzen, wie du's in MySQL auch machst


----------



## derFabi95 (27. Mai 2016)

Okay. Die richtige Fehlermeldung wäre:


Spoiler: Stacktrace





```
[22:43:48] [Server thread/WARN]: Unexpected exception while parsing console command "pe create test"
org.bukkit.command.CommandException: Unhandled exception executing command 'pe' in plugin PetitionPlugin v0.1
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at org.bukkit.craftbukkit.v1_9_R2.CraftServer.dispatchCommand(CraftServer.java:645) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at org.bukkit.craftbukkit.v1_9_R2.CraftServer.dispatchServerCommand(CraftServer.java:631) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.DedicatedServer.aL(DedicatedServer.java:437) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.DedicatedServer.D(DedicatedServer.java:400) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.MinecraftServer.C(MinecraftServer.java:665) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.MinecraftServer.run(MinecraftServer.java:564) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
Caused by: java.lang.ClassCastException: org.bukkit.craftbukkit.v1_9_R2.command.ColouredConsoleSender cannot be cast to org.bukkit.entity.Player
    at me.John_H_Smith.Main.COMMAND_petitionplugin.onCommand(COMMAND_petitionplugin.java:21) ~[?:?]
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    ... 8 more
```


----------



## mrBrown (27. Mai 2016)

Dein Cast `Player player =(Player) sender;` klappt nicht, weil sender kein Player ist.


----------



## derFabi95 (28. Mai 2016)

Okay, demnach sollte ich das vll tatsächlich als Spieler ausführen. Dann ist hier der richtige Stacktrace:


Spoiler: Stacktrace





```
[Server thread/ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'pe' in plugin PetitionPlugin v0.1
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at org.bukkit.craftbukkit.v1_9_R2.CraftServer.dispatchCommand(CraftServer.java:645) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.PlayerConnection.handleCommand(PlayerConnection.java:1349) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.PlayerConnection.a(PlayerConnection.java:1184) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.PlayerConnectionUtils$1.run(SourceFile:13) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_91]
    at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_91]
    at net.minecraft.server.v1_9_R2.SystemUtils.a(SourceFile:45) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.MinecraftServer.D(MinecraftServer.java:726) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.DedicatedServer.D(DedicatedServer.java:399) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.MinecraftServer.C(MinecraftServer.java:665) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at net.minecraft.server.v1_9_R2.MinecraftServer.run(MinecraftServer.java:564) [spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
Caused by: java.lang.NullPointerException
    at me.xxx.Main.COMMAND_petitionplugin.onCommand(COMMAND_petitionplugin.java:61) ~[?:?]
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot_server.jar:git-Spigot-4af49dc-23da8b0]
    ... 15 more
```




Ich blicks einfach nicht. Hab versucht das durch einen Konstruktor wiederherzustellen, allerdings will ich ja die Daten aus der Config via getConfig da eingefügt haben. Die getConfig erkennt eclipse allerdings nicht. Deshalb würde ich gern die bestehende Verbindung 
	
	
	
	





```
mysql = new MySQL(dhost, ddatabase, duser, dpassword);
```
 aus der Main.java verwenden. Wie bekomme ich diese dann in die andere Klasse rein?


----------



## JStein52 (28. Mai 2016)

Das mysql dem COMMAND_petitionplugin als Parameter im Konstruktor mitgeben.


```
this.getCommand("petition").setExecutor(new COMMAND_petitionplugin(mysql));
```

Den passenden Konstruktor musst du dir dann natürlich noch erstellen. Bis jetzt hast du ja da keinen.


----------

