EvidentSolutions / dalesbred

Dalesbred - a database access library for Java
https://dalesbred.org
MIT License
54 stars 15 forks source link

Exceptions #29

Closed Gronis closed 8 years ago

Gronis commented 8 years ago

EDIT: Answer below!

Hi nice lib you have here!

I have a question regarding exceptions. If I example do this:

try {
    ResultTable rt = db.findTable("select * from SomeTable");
} catch (Exception e){
    db.update("create table SomeTable (field int)");
}

An exception is still printed to the console (see print below). Somehow my catch does not "catch" the exception. However the table is still created so it somehow catches the exception. My question is that why is the exception still printed to my console of the exception is handled?

Print:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'db.sometable' doesn't exist
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
    at com.mysql.jdbc.Util.getInstance(Util.java:387)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:942)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3966)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1962)
    at org.dalesbred.Database.lambda$executeQuery$1(Database.java:287)
    at org.dalesbred.Database$$Lambda$46/1734853116.execute(Unknown Source)
    at org.dalesbred.transaction.DefaultTransaction.execute(DefaultTransaction.java:53)
    at org.dalesbred.transaction.DefaultTransactionManager.withNewTransaction(DefaultTransactionManager.java:61)
    at org.dalesbred.transaction.AbstractTransactionManager.withTransaction(AbstractTransactionManager.java:62)
    at org.dalesbred.Database.withTransaction(Database.java:203)
    at org.dalesbred.Database.withTransaction(Database.java:192)
    at org.dalesbred.Database.withTransaction(Database.java:164)
    at org.dalesbred.Database.withCurrentTransaction(Database.java:266)
    at org.dalesbred.Database.executeQuery(Database.java:280)
    at org.dalesbred.Database.findTable(Database.java:542)
    at org.dalesbred.Database.findTable(Database.java:550)

I'm using mysql (as you can tell by the exception log)

Gronis commented 8 years ago

Nevermind. I managed to figure out how to do it :) Just wrap everything inside a transaction and it works ^^

db.withVoidTransaction(t -> {
    try {
        ResultTable rt = db.findTable("select * from SomeTable");
    } catch (Exception e){
        db.update("create table SomeTable (field int)");
    }
});
komu commented 8 years ago

Hi,

That would be one solution, but it could hide some other problems as well. Furthermore, errors when executing SQL could mark the running transaction to be rolled back at the end, causing problems.

Depending on your situation, it's probably better to either query the _informationschema (or use java.sql.DatabaseMetaData) to check the presence of the table or simply use the "if not exist" -variant for the "create table". So it could be as simple as executing this:

db.update("create table if not exist SomeTable(field int)");
Gronis commented 8 years ago

Yes, you are probably right. That is a better solution. Thanks! :)