I have the following code and when exception happens the ExecuteReader() in Catch block will hang the app.
My question is why the hang? I can't perform query inside of Catch block if query exception happens in general?
Try {
// some SQL queries
}
catch (SqlException odbcEx) {
// do some queries with IDbCommand::ExecuteReader()
}
catch (Exception ex) {
// Handle generic ones here.
}
Thanks,
The ExecuteReader() keeps hold of your SQL connection. What you want to do is wrap a using statement round it. Also, you can't perform a SQL query because you have essentially errored and lost scope of your SQL connection variable. If you want, you can do some further SQL in the exception block by instantiating a new instance of your reader and connection, however ideally close of your existing connection before doing so. If you use a datatable you won't keep hold of the SQL connection. Perhaps something to look at.
For example:
using (var conn = new SqlConnection("ConnectionString"))
{
try {
// some SQL queries
}
catch (SqlException odbcEx) {
// do some queries with IDbCommand::ExecuteReader()
}
catch (Exception ex) {
// Handle generic ones here.
}
finally {
conn.Close();
}
}
This way you are disposing of your connection and not keeping hold of it.
Related
I am pondering for a while with the following code:
try (Connection conn = dbHandler.getConnection()) {
// do something with the connection
dbConn.commit();
} catch (SQLException e) {
System.err.println("Too bad!");
e.printStackTrace();
}
Consider my application needs to be resilient to some SQL locking/dead-lock situations, so I would need to do some specific handling inside of the catch block. However, I cannot easily identify, if the exception was thrown during the "do something" part of my code or during autoClose(). And of course, each JDBC driver throws slightly different exceptions and if you throw JDBI in the mix, it gets even more complicated. So you can't really rely on different catch clauses do precisely identify, when the exception got thrown.
The only solution I could come up with is this code:
boolean finishedProcessing = false;
try (Connection conn = dbHandler.getConnection()) {
// do something with the connection
dbConn.commit();
finishedProcessing = true;
} catch (SQLException e) {
if (finishedProcessing) {
// this is an exception during autoClose
System.err.println("Too bad!");
e.printStackTrace();
} else {
// handle rollback cases, retries etc
System.err.println("SQL recovery performed.");
throw e;
}
}
Now the same issue comes up with IOExceptions for File* operations and probably in many other cases.
To be honest, I am just hoping I missed something completely obvious and I appreciate any insight from the Java experts out here.
As stated above, the only solution I found so far is introducing state-variables into the code, which doesn't really make sense to me.
I am fully aware of suppressing exceptions from the autoClose process, when an exception got thrown by the try block, however, as stated above the same kind of exception can be thrown, suppressed and both.
Don't use try-with-resources and add a finally block.
Connection conn = null;
try {
conn = dbHandler.getConnection()
// do something with the connection
dbConn.commit();
}
catch (SQLException e) {
// Handle rollback cases, retries, etc.
System.err.println("SQL recovery performed.");
e.printStackTrace();
}
finally {
if (conn != null) {
try {
conn.close();
}
catch (SQLException xSql) {
System.out.println("Failed to close database connection.");
xSql.printStackTrace();
}
}
}
I have few similar methods and there calls as follows :
methodThrowingException() throws NullPointerException, InterruptedException, TimeoutException {
<method logic>
}
Calling class :
try{
methodThrowingExceptions();
<some other logic>
}
catch (NullPointerException npx) {
npx.printStackTrace();
log more details...
}
catch (InterruptedException inx) {
inx.printStackTrace();
log more details...
}
catch (TimeoutException tox) {
tox.printStackTrace();
log more details..
}
How (if) can I put all of these three in one Custom Exception?
Other than (1) is there a way to optimise the code so that I need not write the entire same statements for multiple methods?
Since Java 7, you can use a multi-catch block:
catch (NullPointerException | InterruptedException | TimeoutException e) {
e.printStackTrace();
log more details...
}
That said, you should never catch NullPointerException: that is a bug, and if it happens, the exception should bubble up. You can't reasonably expect a NPE to happen.
In addition, doing the same thing for an InterruptedException as for the other exceptions is also very dubious. When catching an InterruptedException, you should reset the interrupted flag on the current thread, and stop what you're doing ASAP.
I am trying to do batch inserts into mysql at very high rates. I wanted to try the rewriteBatchedStatements config option as I have read it can make significantly affect performance. When I add the option however I get the following exception:
java.lang.NullPointerException
at com.mysql.jdbc.PreparedStatement.computeMaxParameterSetSizeAndBatchSize(PreparedStatement.java:1694)
at com.mysql.jdbc.PreparedStatement.computeBatchSize(PreparedStatement.java:1651)
at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1515)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1272)
at com.zaxxer.hikari.proxy.StatementProxy.executeBatch(StatementProxy.java:116)
at com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy.executeBatch(PreparedStatementJavassistProxy.java)
This is my code that does the inserts:
try (Connection connection = DBUtil.getInstance().getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(query)) {
connection.setAutoCommit(false);
for (TransactionBatch batch : batches) {
try {
preparedStatement.setString(1, batch.getDeviceID());
preparedStatement.setBinaryStream(2, new ByteArrayInputStream(dataArray));
preparedStatement.addBatch();
} catch (Exception e) {
e.printStackTrace();
}
}
preparedStatement.executeBatch();
} catch (Exception e) {
e.printStackTrace();
}
This is my jdbc url:
jdbc:mysql://url:port/tableName?user=userame&password=password&useServerPrepStmts=false&rewriteBatchedStatements=true
Also I am using HikariCP as my connection pool.
EDIT: Update - looks like the problem relates to having a varbinary(10000) column in the table
The solution was to stop using:
preparedStatement.setBinaryStream(inputstream)
instead I used
preparedStatement.setBytes(byte[])
In order to rewrite it must need to calculate the total size which it can't do upfront from an input stream. It is working great now and my write speeds are awesome!
When saving an object to database using hibernate, it sometimes fails because of certain fields in the object exceeding the maximum varchar length defined in the database.
Therefore I am using the following approach:
Attempt to save
If getting an DataException, I then truncate the fields in the object to the max length specified in the db definition, then try to save again.
However, in the second save after truncation, I'm getting the following exception:
hibernate: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
Here's the relevant code, do you notice anything wrong with it?
public static void saveLenientObject(Object obj){
try {
save2(rec);
} catch (org.hibernate.exception.DataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
saveLenientObject(rec, e);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void saveLenientObject(Object rec, DataException e) {
Util.truncateObject(rec);
System.out.println("after truncation ");
save2(rec);
}
public static void save2(Object obj) throws Exception{
try{
beginTransaction();
getSession().save(obj);
commitTransaction();
}catch(Exception e){
e.printStackTrace();
rollbackTransaction();
//closeSession();
throw e;
}finally{
closeSession();
}
}
All Hibernate exceptions (except for NonUniqueResultException) are irrecoverable. If you get an exception you should close the session and open another one for further operations.
See also:
13.2.3. Exception handling
The hibernate documentaiton is quite clear that once an exception is thrown the session will be left in an inconsistent state so is not safe to use for further operations. I suspect that what you're getting here is that the session is left half saving your first attempt so bad things happen.
Fundamentally you should not rely on database errors to check the length of your fields, instead you should pre-validate this in java code. If you know the lengths enough to truncate, then I suggest you simply call your trucate util every time.
Alternatively use Hibernate Validator to declaratively validate the objects before saving.
I have an if condition which checks for value and the it throws new NumberFormatException
Is there any other way to code this
if (foo)
{
throw new NumberFormatException
}
// ..
catch (NumberFormatException exc)
{
// some msg...
}
If you are doing something such as this:
try
{
// some stuff
if (foo)
{
throw new NumberFormatException();
}
}
catch (NumberFormatException exc)
{
do something;
}
Then sure, you could avoid the exception completely and do the 'do something' part inside the conditional block.
If your aim is to avoid to throw a new exception:
if(foo)
{
//some msg...
} else
{
//do something else
}
Don't throw exceptions if you can handle them in another, more elegant manner. Exceptions are expensive and should only be used for cases where there is something going on beyond your control (e.g. a database server is not responding).
If you are trying to ensure that a value is set, and formatted correctly, you should try to handle failure of these conditions in a more graceful manner. For example...
if(myObject.value != null && Checkformat(myObject.Value)
{
// good to go
}
else
{
// not a good place to be. Prompt the user rather than raise an exception?
}
In Java, you can try parsing a string with regular expressions before trying to convert it to a number.
If you're trying to catch your own exception (why???) you could do this:
try { if (foo) throw new NumberFormatException(); }
catch(NumberFormatexception) {/* ... */}
if you are trying to replace the throwing of an exception with some other error handling mechanism your only option is to return or set an error code - the problem is that you then have to go and ensure it is checked elsewhere.
the exception is best.
If you know the flow that will cause you to throw a NumberFormatException, code to handle that case. You shouldn't use Exception hierarchies as a program flow mechanism.