GeoTools getFeatures takes forever - java

I wrote the following method as an onClick handler. First and second click, I got result from DB. By the third time, the code stopped in the "getFeatures(trgtFilter)" line and didn't return. In debug mode, I saw that it is waiting for DB connection. Can someone tell me what I did wrong? I'm using GeoTools 15 and Oracle 12.
private Geometry getNewGeometry(String refID) throws Exception {
if (trgLayer != null) {
Connection con = null;
OracleConnection oraCon=null;
FeatureIterator<SimpleFeature> itr = null;
try {
con = ((JDBCDataStore) srcLayer.getFeatureSource().getDataStore()).getConnection(Transaction.AUTO_COMMIT);
oraCon = (OracleConnection) new DelegatingConnection(con).getInnermostDelegate();
Filter trgtFilter = editTask.getConfiguration().getReferenceFilter(trgLayer, refID);
FeatureCollection fc = trgLayer.getFeatureSource().getFeatures(trgtFilter);
itr = fc.features();
if (!itr.hasNext())
return null;
...
} catch (Exception e) {
throw e;
} finally {
if (itr != null)
itr.close();
if (oraCon != null) {
try {
oraCon.close();
if (con != null && !con.isClosed())
con.close();
} catch (SQLException e) {
LOGGER.error("", e);
}
}
}
}
}

If the filter is an 'id' filter, it could be that there is no index on that column in the Oracle table. If that's the case, the database will do a full-table scan.
Assuming you have a geospatial index and assuming the user is 'zoomed-in' on a given area, you could add the user viewport's geo-bounds to the query. With that query, the database can use the geo-index.
Alternatively, you can create an index on the fid/id column for the table if look-ups by feature id are going to be common.

Related

How do I perform a simple email/password verification in JSP using a SQL database?

I have the code that successfully establishes a connection to a mySQL database.
String email, password; //assume these are already loaded with user-entered data.
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
return false;
}
Connection conn = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/main", "root", "password123");
} catch (SQLException e) {
return false;
}
//perform my database actions here///////////////
///////////////////////////////////////////////////
try {
conn.close();
} catch (SQLException e) {
return false;
}
I have a couple of strings in the scope of the code above that already have the email and password entered by a user on a login page. I need to look through the database for a matching email address and then verify that the password matches what the user entered in the form.
My table has 3 columns: id, email, and password.
I have pushed two rows into the table using the sql workbench
1 | email#gmail.com | password1
2 | email2#gmail.com | password2
I'm assuming in pure SQL I have to do something like
SELECT * FROM users WHERE email LIKE 'email#gmail.com' AND password LIKE 'password1';
But I'm not quite sure how to actually send these SQL commands to the database and receive info back using JSP. Also, I'm not entirely sure my SQL logic is the ideal way to verify a password. My thinking with the SQL command above was that if the database finds any row that meets the conditions, then the email/password combination are verified. Not sure if this is a great way to do it though. I'm not looking for the most secure and complicated way, I'm just looking for the simplest way that makes sense at the moment. Every tutorial I find seems to do it differently and I'm a bit confused.
Here's an example you can use from something I've worked on (I'm assuming that the connection "conn" is obvious):
PreparedStatement st = null;
ResultSet rec = null;
SprayJobItem item = null;
try {
st = conn.prepareStatement("select * from sprayjob where headerref=? and jobname=?");
st.setString(1, request.getParameter("joblistref"));
st.setString(2, request.getParameter("jobname"));
rec = st.executeQuery();
if (rec.next()) {
item = new SprayJobItem(rec);
}
} catch (SQLException ex) {
// handle any errors
ReportError.errorReport("SQLException: " + ex.getMessage());
ReportError.errorReport("SQLState: " + ex.getSQLState());
ReportError.errorReport("VendorError: " + ex.getErrorCode());
} catch (Exception ex) {
ReportError.errorReport("Error: " + ex.getMessage());
} finally {
// Always make sure result sets and statements are closed,
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
;
}
ps = null;
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
;
}
rs = null;
}
}
In your case instead of item = new SprayJobItem(rec);
you would have code that notes that the user is valid as the record has been found.

Web Service Method- not returning data from the if else statement found in try catch block

I have a web service method to compare templates, however it does not perform the code in the if else statement found in the try catch block instead it returns the last return statment which says "error". Any idea what am doing wrong? It was supposed to return "finger was verified" or "finger was NOT verified".
#WebMethod(operationName = "verify")
public String verify(#WebParam(name = "name") String name, #WebParam(name = "ftset") String ftset) {
Connection con = null;
String dbTemplate = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/biodb", "root", "1234");
PreparedStatement st;
st = con.prepareStatement("select template from info where name = ? ");
st.setString(1, name);
ResultSet result = st.executeQuery();
if (result.next()) { //.next() returns true if there is a next row returned by the query.
dbTemplate = result.getString("template");
byte[] byteArray = new byte[1];
byteArray = hexStringToByteArray(dbTemplate);
DPFPTemplate template = DPFPGlobal.getTemplateFactory().createTemplate();
template.deserialize(byteArray);
byte[] fsArray = new byte[1];
fsArray = hexStringToByteArray(ftset);
DPFPFeatureSet features = null;
features.deserialize(fsArray);
DPFPVerification matcher = DPFPGlobal.getVerificationFactory().createVerification();
DPFPVerificationResult fresult = matcher.verify(features, template);
if (fresult.isVerified()) {
return "The fingerprint was VERIFIED.";
} else {
return "The fingerprint was NOT VERIFIED.";
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
if (con != null) {
try {
con.close();
} catch (SQLException e) {
}
}
}
return "error";
}
Any idea what am doing wrong?
Well, the behaviour you've described is what will happen if an exception is thrown, due to this:
catch (Exception e) {
System.out.println(e.getMessage());
}
If anything goes wrong, you write something to System.out (which presumably you're not looking at, otherwise you'd have seen what's happened) and continue by returning "error".
To start with, I'd recommend catching specific exceptions - and change how you're logging the exception so that it's more obvious in your diagnostics.
Additionally, you'll get this behaviour if result.next() returns false. This isn't clear from the code you've posted, due to the lack of consistent indentation. You should definitely fix the indentation - readability is absolutely crucial.
Next, work out what you want to happen if result.next() returns false. Is that an error? Should it actually just return the "not verified" case?

Java ResultSet already closed exception while querying user data

As I've started in the title, while I'm querying for user data in my java application, I get following message: "Operation not allowed after ResultSet closed".
I know that this is happens if you try to have more ResultSets opened at the same time.
Here is my current code:
App calls getProject("..."), other 2 methods are there just for help. I'm using 2 classes because there is much more code, this is just one example of exception I get.
Please note that I've translated variable names, etc. for better understanding, I hope I didn't miss anything.
/* Class which reads project data */
public Project getProject(String name) {
ResultSet result = null;
try {
// executing query for project data
// SELECT * FROM Project WHERE name=name
result = statement.executeQuery(generateSelect(tProject.tableName,
"*", tProject.name, name));
// if cursor can't move to first place,
// that means that project was not found
if (!result.first())
return null;
return user.usersInProject(new Project(result.getInt(1), result
.getString(2)));
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (BadAttributeValueExpException e) {
e.printStackTrace();
return null;
} finally {
// closing the ResultSet
try {
if (result != null)
result.close();
} catch (SQLException e) {
}
}
}
/* End of class */
/* Class which reads user data */
public Project usersInProject(Project p) {
ResultSet result = null;
try {
// executing query for users in project
// SELECT ID_User FROM Project_User WHERE ID_Project=p.getID()
result = statement.executeQuery(generateSelect(
tProject_User.tableName, tProject_User.id_user,
tProject_User.id_project, String.valueOf(p.getID())));
ArrayList<User> alUsers = new ArrayList<User>();
// looping through all results and adding them to array
while (result.next()) { // here java gets ResultSet closed exception
int id = result.getInt(1);
if (id > 0)
alUsers.add(getUser(id));
}
// if no user data was read, project from parameter is returned
// without any new user data
if (alUsers.size() == 0)
return p;
// array of users is added to the object,
// then whole object is returned
p.addUsers(alUsers.toArray(new User[alUsers.size()]));
return p;
} catch (SQLException e) {
e.printStackTrace();
return p;
} finally {
// closing the ResultSet
try {
if (result != null)
result.close();
} catch (SQLException e) {
}
}
}
public User getUser(int id) {
ResultSet result = null;
try {
// executing query for user:
// SELECT * FROM User WHERE ID=id
result = statement.executeQuery(generateSelect(tUser.tableName,
"*", tUser.id, String.valueOf(id)));
if (!result.first())
return null;
// new user is constructed (ID, username, email, password)
User usr = new user(result.getInt(1), result.getString(2),
result.getString(3), result.getString(4));
return usr;
} catch (SQLException e) {
e.printStackTrace();
return null;
} catch (BadAttributeValueExpException e) {
e.printStackTrace();
return null;
} finally {
// closing the ResultSet
try {
if (result != null)
result.close();
} catch (SQLException e) {
}
}
}
/* End of class */
Statements from both classes are added in constructor, calling connection.getStatement() when constructing each of the classes.
tProject and tProject_User are my enums, I'm using it for easier name handling. generateSelect is my method and should work as expected. I'm using this because I've found out about prepared statements after I have written most of my code, so I left it as it is.
I am using latest java MySQL connector (5.1.21).
I don't know what else to try. Any advice will be appreciated.
Quoting from #aroth's answer:
There are many situations in which a ResultSet will be automatically closed for you. To quote the official documentation:
http://docs.oracle.com/javase/6/docs/api/java/sql/ResultSet.html
A ResultSet object is automatically closed when the Statement object that generated
it is closed, re-executed, or used to retrieve the next result from a sequence of
multiple results.
Here in your code , You are creating new ResultSet in the method getUser using the same Statement object which created result set in the usersInProject method which results in closing your resultset object in the method usersInProject.
Solution:
Create another statement object and use it in getUser to create resultset.
It's not really possible to say definitively what is going wrong without seeing your code. However note that there are many situations in which a ResultSet will be automatically closed for you. To quote the official documentation:
A ResultSet object is automatically closed when the Statement object
that generated it is closed, re-executed, or used to retrieve the next
result from a sequence of multiple results.
Probably you've got one of those things happening. Or you're explicitly closing the ResultSet somewhere before you're actually done with it.
Also, have you considered using an ORM framework like Hibernate? In general something like that is much more pleasant to work with than the low-level JDBC API.

"DatabaseIOException: File system error (12)" when using database?

I have created a tab bar which appears when I enter first time in database screen, this code is working fine. But when we go on another tab and again go on database screen tab it throws an exception
net.rim.device.api.database.DatabaseIOException: File system error (12)
I have closed database properly.
I Have close database in finally block.Database is closing each time when I am moving the tab
This is my code:
Database d = null;
URI _uri = null;
Statement st = null;
Cursor c = null;
try
{
_uri=URI.create("file:///SDCard/MyBudgetTracker.db");
if (DatabaseFactory.exists(_uri)) {
d=DatabaseFactory.openOrCreate(_uri,new DatabaseSecurityOptions(false));
st = d.createStatement("SELECT * FROM "+Globalvalue.planCategoryTable);
st.prepare();
c = st.getCursor();
Row r;
int i = 0;
while(c.next()) {
r = c.getRow();
r.getString(0);
i++;
}
if (i==0)
{
add(new RichTextField("No data in the User table."));
}
}
}catch (Exception e)
{
System.out.println(e.getMessage());
System.out.println(e);
e.printStackTrace();// TODO: handle exception
} finally {
try {
if (DatabaseFactory.exists(_uri)) {
if (c != null) {
c.close();
}if (st != null) {
st.close();
} if (d != null) {
d.close();
}
}
} catch (Exception e2) {
// TODO: handle exception
}
}
You are retrieving values onto your selected tab from database?
You can think of this alternative method of opening and closing database.It always yields lesser errors.
try
{
//Open or create the database
Database db = DatabaseFactory.openOrCreate("MyBudgetTracker.db");
//Retrieve Data from db
Statement statement1 = db.createStatement("SELECT * FROM "+Globalvalue.planCategoryTable);
statement1.prepare();
statement1.execute();
statement1.close();
db.close();
}
catch(DatabaseException dbe)
{
System.err.println(dbe.toString());
}
Else you can include a db open statement on each of ur tabs before u fetch the value albeit it wud increase ur programming code lines.

Java : Insert query-Exception

I have a doubt regarding database operation.I have one insert query that should run for 10 times. the loop starts and inserted 4 or 5 val while inserting 6th, the db connection got failed for a while and again connected. then what will happen,
whether it skips that particular val or throws exception or roll back th entire operation?
EDIT : Sample Code
try
{
String sql_ji_inser="insert into job_input values (?,?)";
PreparedStatement pst_ji_inser=OPConnect.prepareStatement(sql_ji_inser);
for(int i=0;i<v_new_data.size();i++)
{
Vector row=new Vector();
row=(Vector)v_new_data.get(i);
job_id=Integer.parseInt(row.get(0).toString());
item_no=Integer.parseInt(row.get(1).toString());
pst_ji_inser.setInt(1,job_id);
pst_ji_inser.setInt(2,item_no);
pst_ji_inser.addBatch();
}
System.out.println("No of rows inserted"+pst_ji_inser.executeBatch().length);
}
catch(Exception ex)
{
System.out.println("********Insert Exception*********************");
ex.printStackTrace();
return false;
}
Is this the right way
try
{
int count=0;// for checking no of inserting values
OPConnect.setAutoCommit(false);
String sql_ji_inser="insert into job_input values (?,?)";
PreparedStatement pst_ji_inser=OPConnect.prepareStatement(sql_ji_inser);
for(int i=0;i<v_new_data.size();i++)
{
job_id=Integer.parseInt(row.get(0).toString());
item_no=Integer.parseInt(row.get(1).toString());
pst_ji_inser.setInt(1,job_id);
pst_ji_inser.setInt(2,item_no);
pst_ji_inser.addBatch();
count++;
}
int norowinserted=pst_ji_inser.executeBatch().length;
if(count==norowinserted)
{
OPConnect.commit();
}
}
catch(Exception ex)
{
System.out.println("********Insert Exception*********************");
OPConnect.rollback();
ex.printStackTrace();
return false;
}
That depends on how you're inserting the rows. If you're inserting them in a single transaction on a connection which has auto-commit turned off by connection.setAutoCommit(false) and you're commiting the connection after completing the insert queries using connection.commit() and you're explicitly calling connection.rollback() inside the catch block, then the entire transaction will be rolled back. Otherwise, you're dependent on environmental factors you have no control over.
See also:
When to call rollback?
Update: here's a rewrite of your code. Note that the connection and statement should be declared before the try, acquired in the try and closed in the finally. This is to prevent resource leaking in case of exceptions.
String sql = "insert into job_input values (?, ?)";
Connection connection = null;
PreparedStatement statement = null;
try {
connection = database.getConnection();
connection.setAutoCommit(false);
statement = connection.prepareStatement(sql);
for (List row : data) {
statement.setInt(1, Integer.parseInt(row.get(0).toString()));
statement.setInt(2, Integer.parseInt(row.get(1).toString()));
statement.addBatch();
}
statement.executeBatch();
connection.commit();
return true;
} catch (SQLException e) {
if (connection != null) try { connection.rollback(); } catch (SQLException logOrIgnore) {}
e.printStackTrace();
return false;
} finally {
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
I am by the way not a fan of returning a boolean here. I'd just make the method void, let the catch throw e and put the calling code in a try-catch.

Categories

Resources