Caught a throwable exception during processing Closed Resultset: next - exception

So I did try checking for answers before I could ask this question again, I'm getting a closed ResultSet exception for my code below.
The same code worked on development environment when tested for a small set of records. But on QA environment the exception is encountered for 200-300 records being fetched by the query as well.
My question is, if there is no close statement or close connection code why is the closed resultset exception thrown at the While loop in the code below?
public void extractRecordsAndUpdateData() throws Throwable {
ConnectionManager mgr =null;
/*
* Some authentication code here for user authentication to allow access in the application
*/
Connection c = null;
try {
mgr = mServiceLocator.getConnectionManager();
}
catch (Exception newex) {
newex.printStackTrace();
customLogWriter.logEntry("Got a Exception during authentication " + newex.getMessage());
}
PreparedStatement pSql = null;
ResultSet myResultSet = null;
try {
c = mgr.getConnection(mgr.getSiteName());
pSql = c.prepareStatement(extractSQL); // extractSQL is a simple select statement fetching records from DB to be processed in the while loop below.
myResultSet = pSql.executeQuery();
}catch(SQLException ex){customLogWriter.logEntry("Error " + ex.getMessage());}
List<List> outerList=new ArrayList<List>();
while (myResultSet.next()) // Exception encountered on this line of code
{
/*Do some processing*/
}
customLogWriter.close();
}

Poorly structured exception handling. The ResultSet.next() loop should be inside the try block. You should only have one try and one catch (SQLException ...) here.
Don't write code like this. Code that depends on the success of code in a prior try block should be inside that try block.

Related

EntityFramework exception: How can i see the real query

Sometimes i have an EntityFramework exception where calling SaveChanges.
I see this kind of message: "An error occurred while updating the entries. See the inner exception for details."
I have logged the stack trace, the inner exception and stuff but there is no clear explanation of the problem. I would like to see the real query (it is a mysql database), with the parameters. Do you know how i can see or log the real query ?
Thanks
You can use DbEntityValidationException handler which will let you know what was wrong precisely.
try{
//Your code here
}
catch (DbEntityValidationException ex)
{
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
var fullMessageError = string.Join("; ", errorMessages);
var exceptionMessage = string.Concat(ex.Message, "Exact Message " + fullMessageError);
}
catch (Exception ex)
{
//General Exception here
}
You can set log property of dbContext.Database and log the actual queries generated by EF.
using (var context = new MyDBContext())
{
context.Database.Log = Console.Write; // This is where you setup where to log queries
// Your code here...
}
There is a detailed documentation on MSDN https://msdn.microsoft.com/en-us/data/dn469464.aspx

JUnit - How to make test case pass if it times out?

I ran into a dilemma with making a test pass if it times out.
#Test(timeout=1, expected=Exception.class)
public void testMovesToSolveMaximum() {
PuzzleSolver pS = createSimplePuzzleSolver(maximumPuzzleStateA, maximumPuzzleStateB);
PuzzleState goal = new SimplePuzzleState();
goal.configureState(maximumPuzzleStateB);
checkThatComputedSolutionIsCorrect(pS, goal);
}
However, the test case fails due to timeout even though I specified that is the expected result.
If I understand the question correctly then you are observing the specific behavior due to the way that the default JUnit runner is evaluating the whole test:
After realizing that there is a timeout set on your test method it runs it in a different thread and is waiting for the result. As the timeout in your example is set to 1[ms] I believe that it reaches the timeout before the test actually finishes which makes the runner throw the timeout exception (that is indeed a java.lang.Exception) which you thought needed to be caught by the expected attribute in the Test annotation. But the attribute expected on the Test annotation is evaluating only the exceptions thrown from the test method and not from the timeout checking mechanism. In other words the expected exception mechanism is not working for the timeout exception throw by the f/w and not by a test.
You can explore this yourself starting in BlockJUnit4ClassRunner class in JUnit (relevant part to start from. NOTE: it is not so easy to go over the code and understand the flow...):
protected Statement methodBlock(FrameworkMethod method) {
Object test;
try {
test = new ReflectiveCallable() {
#Override
protected Object runReflectiveCall() throws Throwable {
return createTest();
}
}.run();
} catch (Throwable e) {
return new Fail(e);
}
Statement statement = methodInvoker(method, test);
statement = possiblyExpectingExceptions(method, test, statement);
statement = withPotentialTimeout(method, test, statement);
statement = withBefores(method, test, statement);
statement = withAfters(method, test, statement);
statement = withRules(method, test, statement);
return statement;
}

Spring MVC Exceptions

I have the following code in the Controller class and for some reason although i have exception handling implemented as well as a try.....catch block i am still unable to capture my exceptions.
I am just executing a test, in the DAO class i change the sql string that inserts into the database to leave out a column just so the DAO will fail. The DAO class fails and the error is written to the logs however even thou the officerManager.RegisterOfficer(officer) was not successful the code goes on to return the model.addAttribute("results","Record Was Saved").
This is not accurate and i would like for the controller to throw an error. Under is the code.
Controller
#RequestMapping(value="officer_registration.htm", method=RequestMethod.POST)
public ModelAndView handleRequest(#Valid #ModelAttribute Officers officer,BindingResult result,ModelMap m,Model model,HttpServletRequest request,HttpServletResponse response)throws Exception{
try{
if(result.hasErrors()){
model.addAttribute("division", myDivision);
model.addAttribute("position", myPosition);
model.addAttribute("gender", myGender);
return new ModelAndView("officer_registration");
}else{
//check the request if its an update or an insert
String user_request = request.getParameter("user_request");
logger.info("The Users Request Was " + user_request);
if (user_request.equals("Save")){
officerManager.RegisterOfficer(officer);
model.addAttribute("results","Record Was Saved");
}else{
officerManager.UpdateOfficer(officer);
model.addAttribute("results","Record Was Updated");
}
model.addAttribute("division", myDivision);
model.addAttribute("position", myPosition);
model.addAttribute("gender", myGender);
return new ModelAndView("officer_registration");
}
}catch(Exception e ){
model.addAttribute("division", myDivision);
model.addAttribute("position", myPosition);
model.addAttribute("gender", myGender);
model.addAttribute("results","Error: Unable to Save Record!");
return new ModelAndView("officer_registration");
}
}
DAO
public void saveOfficer(Officers officer) {
logger.info("In saveOfficer");
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try{
int count = getJdbcTemplate().update("INSERT INTO crimetrack.tblofficers (userName,password, fName, lName, oName, divisionNo, positionId, emailAdd, startDate, endDate, genderId,phoneNo, dob,badgeNo) "+
"VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
, new Object[]{officer.getUserName(),StringSecurity.EncryptString(officer.getPassword()),officer.getfName(),
officer.getlName(),officer.getoName(),officer.getDivisionNo(),officer.getPositionId(),
officer.getEmailAdd(),officer.getStartDate(),officer.getEndDate(),officer.getGenderId(),
officer.getPhoneNo(),officer.getDob(),officer.getBadgeNo()});
logger.info(count +" Rows affected in tblOfficers");
}catch(Exception e){
logger.error("Could not save officer ", e);
}
}
You're not allowing the error to bubble up back to the controller.
You're handling the exception within the DAO, in which case the method exits normally, and no exception is caught within the Controller.
Either don't surround the DAO with a try catch and let the exception bubble back to the controller (recommended), or catch and rethrow the exception (if you follow this route, throw as a RuntimeException, either create your own, or rethrow as a RuntimeException, that way you won't have to catch all the way through the call stack.)
Also, it's generally frowned upon to catch generic exception as it is tougher to nail down exactly what caused it unless you look within the logs. Knowing which exceptions to handle ahead of time is usually better practice.

How to handle deeply nested exception in struts2?

My struts2 webapp makes use of a SQL database. Within the DB access code, I've written a basic try/catch handler that catches SQL or general exceptions, writes the detail to a log file, and then continues. The hierarchy of classes is as follows:
Action method -> get or set method on Model -> DB access.
//Action method in action class
public string doActionMethod() throws Exception
{
String results = SampleModel.getResults();
}
//Model method in model class
public string getResults() throws Exception
{
String results = DBLayer.runQuery("SELECT Results FROM SampleTable WHERE Value='1');
}
//Method that queries database in DB access class
public string runQuery() throws Exception
{
ResultSet rs = null;
Connection dbConnection = null;
PreparedStatement preparedStatement = null;
dbConnection = MSSQLConnection.getConnection();
preparedStatement = dbConnection.prepareStatement(sqlQuery);
//run SQL statements
return String(rs.get(0));
}
I'd like caught exceptions to bubble up to the Action level, so that I can forward them to an appropriate error page. Is there a better way to do this than adding a "throws Exception" to the method signature?
Since you have no hope of recovery, throw an application-specific RuntimeException.
Use standard Struts 2 declarative exception handling to get your app to the appropriate error page.

SQLException, ResultSet closed but I can figure out why

I'm having a problem with java.sql.ResultSet, I have a java.sql.PreparedStatement on which I run executeQuery() to return a ResultSet yet when I try to get the results from the query I'm getting an Exception thrown:
Exception: java.sql.SQLException Message: Operation not allowed after
ResultSet closed.
From searching online it looks like a ResultSet can end up being closed for a few reason:
The PreparedStatement object that generated it is closed.
The PreparedStatement object that generated it is re-executed.
The PreparedStatement object that generated it is used to retrieve the next result from a sequence of multiple results.
Closing the Connection which was used to generate the PreparedStatement.
I checked my code and do none of those things. Below is a snippet of the code that causes the problem:
PreparedStatement psAccountPartyIdByEmail = null;
....
try {
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
String email = nextLine[0];
.....
try {
if (psAccountPartyIdByEmail == null) {
psAccountPartyIdByEmail = session.connection().prepareStatement(SQL_GET_ACCOUNTPARTYID_BY_EMAILADDRESS);
}
psAccountPartyIdByEmail.setString(1, email);
ResultSet partyIds = psAccountPartyIdByEmail.executeQuery();
while (partyIds.next()) {
String partyId = partyIds.getString(1);
.....
}
} catch (SQLException e) {
Debug.logError(e, "Encountered SQLException while running group service.", MODULE);
}
}
} catch (IOException e) {
Debug.logError(e, "Problem reading line in file", MODULE);
}
The Exception is thrown when trying to execute: while (partyIds.next()) {
Like I stated I never close the connection or statement and as you can see I don't reuse the statement prior to trying to view my result.
Thanks for he help...
Marc
I don't know if this will fix this problem but you can/should move
if (psAccountPartyIdByEmail == null) {
psAccountPartyIdByEmail = session.connection().prepareStatement(SQL_GET_ACCOUNTPARTYID_BY_EMAILADDRESS);
}
outside of the while loop.
Also, close the ResultSet after you've processed the rows.
Then, when you're all done close your statement and connection.