java - MySQLNonTransientConnectionException when getting player stats -
i'm storing player stats minigame in sql database , i'm getting following error while loading stats:
com.mysql.jdbc.exceptions.jdbc4.mysqlnontransientconnectionexception: no operations allowed after connection closed. [23:37:09] [server thread/warn]: @ sun.reflect.nativeconstructoraccessorimpl.newinstance0(native method) [23:37:09] [server thread/warn]: @ sun.reflect.nativeconstructoraccessorimpl.newinstance(unknown source) [23:37:09] [server thread/warn]: @ sun.reflect.delegatingconstructoraccessorimpl.newinstance(unknown source) [23:37:09] [server thread/warn]: @ java.lang.reflect.constructor.newinstance(unknown source) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.util.handlenewinstance(util.java:425) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.util.getinstance(util.java:408) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:918) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:897) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:886) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.sqlerror.createsqlexception(sqlerror.java:860) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.connectionimpl.throwconnectionclosedexception(connectionimpl.java:1187) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.connectionimpl.checkclosed(connectionimpl.java:1182) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.connectionimpl.preparestatement(connectionimpl.java:4035) [23:37:09] [server thread/warn]: @ com.mysql.jdbc.connectionimpl.preparestatement(connectionimpl.java:4004)
code:
public void loadplayer(player p) { if (!isplayerindatabase(p)) { bukkit.getscheduler().runtaskasynchronously(main.getinstance(), new runnable() { @override public void run() { try (connection connection = sqlconnection.c) { preparedstatement insert = connection.preparestatement( "insert `murderdata` (uuid, wins, deaths, loses, kills, score) values (?, ?, ?, ?, ?, ?)"); insert.setstring(1, p.getuniqueid().tostring()); insert.setint(2, 0); insert.setint(3, 0); insert.setint(4, 0); insert.setint(5, 0); insert.setint(6, 0); insert.execute(); closepreparedstatement(insert); } catch (sqlexception e) { e.printstacktrace(); } } }); } if (isplayerindatabase(p)) { bukkit.getscheduler().runtaskasynchronously(main.getinstance(), new runnable() { @override public void run() { try (connection connection = sqlconnection.c; preparedstatement select = connection.preparestatement( "select * `murderdata` uuid='" + p.getuniqueid().tostring() + "'")) { resultset result = select.executequery(); if (result.next()) { if (getplayerdata(p) != null) { getplayerdata(p).adddeaths(result.getint("deaths")); getplayerdata(p).addkill(result.getint("kills")); getplayerdata(p).addwins(result.getint("wins")); getplayerdata(p).addlose(result.getint("loses")); getplayerdata(p).addscore(result.getint("score")); } closeresultset(result); } } catch (sqlexception e) { e.printstacktrace(); } } }); } }
the error @ code:
preparedstatement select = connection.preparestatement( "select * `murderdata` uuid='" + p.getuniqueid().tostring() + "'")) {
full code:
public boolean isplayerindatabase(player p) { try (connection connection = sqlconnection.c; preparedstatement select = connection.preparestatement( "select * `murderdata` uuid='" + p.getuniqueid().tostring() + "'")) { resultset result = select.executequery(); if (result.next()) { result.close(); return true; } } catch (sqlexception e) { e.printstacktrace(); } return false; }
side question: should close result set , prepared statements after completing process? , should instantly or delay?
it seems have taken try-with-resources statement other code without understanding does. link:
the try-with-resources statement try statement declares 1 or more resources. resource object must closed after program finished it. try-with-resources statement ensures each resource closed @ end of statement. object implements java.lang.autocloseable, includes objects implement java.io.closeable, can used resource.
in other words, when use syntax
try (connection connection = sqlconnection.c) { // ... }
you implicitly calling close()
on sqlconnection.c
, not assigned again. therefore, next time try query database connection, still closed, error.
a simple fix move declaration of local variable connection
out of try-with-resources statement not closed @ end of method. should @ use try-with-resources syntax elsewhere in program , make sure you're not closing don't want close.
this fixed version of code (from pastebin linked in comment):
public boolean isplayerindatabase(player p) { connection connection = sql.getconnection(); try (preparedstatement select = connection.preparestatement( "select * `murderdata` uuid='" + p.getuniqueid().tostring() + "'")) { resultset result = select.executequery(); if (result.next()) { closeresultset(result); return true; } } catch (sqlexception e) { e.printstacktrace(); } return false; }
additionally, in loadplayer()
method, can replace 2 if
statements this:
if (isplayerindatabase(p)) { // code if player in database } else { // code if player not in database }
Comments
Post a Comment