Google App Engine Query Not Working in Java - java

Riddle me this Stackoverflow:
I have a query that I am sending to GAE. The query (When in String format) looks like this:
SELECT * FROM USER WHERE USER_ID = 5884677008
If I go to the GAE console and type it in via a manual GQL query, it returns the item just fine. If I browse via the GUI and scroll to it, I can see it just fine. But when I call it from the Java code, it returns nothing every time.
code:
I have already confirmed the query is correct as I printed it out as a String just so I can test it.
Anyone have any idea what is going on with this?
q = new Query(entityName); //entityName = "User", confirmed
q.setFilter(filter); //filter = "USER_ID = 5884677008", confirmed
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
PreparedQuery pq = datastore.prepare(q);
/*
This always is empty here. Calling either pq.countEntities()); or
pq.toString()); returns size 0 or a String of nothing.
*/
Thanks!
-Sil
Edit: I Do have an index built, but it did not seem to help with the problem.

From the docs, you don't necessarily need to do toString. Have you tried asIterable or asSingleEntity on pq? Something like:
PreparedQuery pq = datastore.prepare(q);
for (Entity result : pq.asIterable()) {
String test = (String) result.getProperty("prop1");
}
That's if you have multiple entries. In the event you only have one:
PreparedQuery pq = datastore.prepare(q);
Entity result = pq.asSingleEntity();
String test = (String) result.getProperty("prop1");
Basically, if you don't call asIterable or asSingleEntity, the query is JUST prepared and doesn't run

Took quite a bit of testing, but found the issue.
The problem revolved around the filter being set. If I removed the filter, it worked fine (but returned everything). Turns out, what was being passed as a filter was a String version of the user_id as opposed to the Long version of it. There was really no way to tell as the exact SQL query DID NOT read ( SELECT * FROM USER WHERE USER_ID = "5884677008" ) when I printed it, which would have been a dead giveaway.
I changed the passed filter parameter (which I had stored in a hashmap of (String, Object) btw) from a String to a Long and that solved the issue.
One thing to point out though, as #Patrice brought up (And as I excluded from my code while posting to save space), to actually iterate through the list of results, you do need to call a method against it (Either .asIterable() or .asSingleEntity() ).
You actually can check against the number of returned entities / results by calling pq.countEntities() and it will return the correct number even before you call a formatting method against the pq, but as #tx802 pointed out, it is deprecated, and despite the fact that it worked for me, someone in the future using this post as a reference may not have it work for them.

Related

How can I get AWS Log insight QueryInfo status on demand with Java SDK?

I created a log insight query and would like to get its results once the query is in "completed" status, otherwise I wont get any results if the query is still in "running" status.
There are two problems that I am facing here:
When I create a DescribeQueriesRequest I cannot specify the query request ID, only the LogGroup. According to AWS documentation, it should return the last queries executed on this log group - but is it 100% reliable? I am asking that because I then need to set maximum results and I wouldn't like set it to more than one ad start iterating through the different results, compare to my queryId and make sure that I am inspecting the correct query status.... The code looks like:
DescribeQueriesRequest describeQueriesRequest = new DescribeQueriesRequest();
describeQueriesRequest.setLogGroupName(logGroupName);
describeQueriesRequest.setMaxResults(1);
Once I execute the describeQueries API, I get a list of QueryInfo objects that are not getting updated... So in order to get the current status of my query, I need to execute describeQueries again, fetch QueryInfo and check for the query status repeatedly until I get to Complete status... Here is how I am currently going about this:
DescribeQueriesResult describeQueriesResult = logsClient.describeQueries(describeQueriesRequest);
List<QueryInfo> queries = describeQueriesResult.getQueries();
QueryInfo queryInfo = queries.get(0);
boolean queryRunningStatus = true;
while (queryRunningStatus){
if (queryInfo.getStatus().equals(QueryStatus.Running.toString())){
describeQueriesResult = logsClient.describeQueries(describeQueriesRequest);
queries = describeQueriesResult.getQueries();
queryInfo = queries.get(0);
} else if (queryInfo.getStatus().equals(QueryStatus.Complete.toString())){
queryRunningStatus = false;
}
}
Maybe that's the only way to fetch the query status but with my experience with amazon SDK, it is usually designed better so I expect to get a QueryInfo object by queryId and then poll its status instead of going through the very awkward way I have shared above. Am I missing something or that is the only way to go about this?

Using the 'astar' function of OrientDB: an SQL call in Java

I'm using OrientDB to represent large city maps and calculate the shortest traversal times between a pair of nodes when the need arises. I have the following method:
public void getShortestPath(int from, int to){
String query = "SELECT astar(?, ?, time, direction=OUT, customHeuristicFormula=EUCLIDEAN) FROM V";
OResultSet set = db.query(query, getNode(from).getProperty("#rid"), getNode(to).getProperty("#rid"));
}
The getNode(nodeID) method returns the OVertex object present in the database, hence we can identify the #rid. Clearly, this method serves no purpose as is.
My issue comes when trying to call the astar query on the database (i.e. line two of the method). I'm getting the following error: OCommandSQLParsingException: Error parsing query upon reaching the first ( (i.e. error encountering the open bracket). Removing the brackets entirely simply resulted in the same error occurring on the # in front of the first #rid value.
I can't seem to find any example of using this function in practice, and (at least I think) I'm using the function call as suggested by the documentation. Look forward to hearing your thoughts.
I'm using the most recent version of OrientDB: 3.2.3
Turns out the error had nothing to do with the bracket itself. Passing the "direction='OUT'" and "customHeuristicFormula='EUCLIDEAN'" parameters in as part of the string was the problem. The below block did the trick.
String sql = "SELECT ASTAR(" + getNode(from).getProperty("#rid") + ", " + getNode(to).getProperty("#rid") + ", time) FROM V";
try(OResultSet set = db.query(sql, "direction='OUT'", "customHeuristicFormula='EUCLIDEAN'")) {
// some code...
}

Retrieving full objects from a query done via Bolt protocol

In Neo4J, I want to use the bolt protocol.
I installed the 3.1 version of Neo4J.
I my Java project, that already works well with normal HTTP Rest API of Neo4J, I integrate with Maven the needed drivers and achieve to perform request with BOLT.
The problem is everywhere you make a search about bolt they give example like this one :
MATCH (a:Product) return a.name
But I don't want the name, I want all the data of all product, what ever i know or not before what are these columns, like here:
MATCH (a:Product) return * --> here I retrieve only the ids of nodes
I found there https://github.com/neo4j-contrib/neo4j-jdbc/tree/master/neo4j-jdbc-bolt we can "flatten" the result but it seems to not work or I didn't understand how it works:
GraphDatabase.driver( "bolt://localhost:7687/?flatten=-1", AuthTokens.basic( "neo4j", "......." ) );
I put the ?flatten=-1 at the end of my connection address... but that changed nothing.
Anyone can help? Or confirm it's not possible or not working ?
Thanks
Ok I understood my error, I didn’t dig enough in the object returned. So used to have a JSON formatted response, I didn’t see that I have to search in the StatementResult object to find the wanted object with its properties. In fact Eclipse in the “expressions” shows “in fly” only the ids, but inside the object data are there.
Record oneRecord = rs.next();
String src = oneRecord.get("m").get("source");
That way I can reconstruct my object

Can I get the string from preparedStatem.setString()?

I have a problem - I create my SQL queries dynamically and basing on user input options. So the user has 5 parameters (actually it's more) and he can choose to use some of them (all if he wants) or none and specify their value in the query. So I construct my query String (basic the WHERE conditions) by checking if a parameter was selected and if a value was provided. However now there is the problem of special characters like '. I could try to use replaceAll("'", "\\") but this is quite dull and I know that preparedStatement.setString() does the job better. However for me I would need than to check again if the parameter was provided and if the previous one were also (to specify the poison of ? and connect it to the right parameter). This causes a lot of combinations and does not look elegant.
So my question is - can I somehow receive the string preparedStatement.setString() produces? Or is there a similar function that would do the same job and give me the String so I can put it in the query manually.
Maybe the intro was too long but someone might have a better idea and I wanted to explain why I need it.
What you can do is construct the basic, unparameterized SQL query based on whether the parameters were specified, and then use the prepared statement to fill in the parameters.
It could look something like this (rough sketch):
Map<String, Object> parameterValues = /*from user*/;
List<String> parameterNames = Arrays.asList("field1", "field2", "field3");
List<Object> valueList = new ArrayList<Object>();
StringBuilder statementBuilder = new StringBuilder("select * from table where ");
for ( String parameterName : parameterNames ) {
if ( parameterValues.containsKey(parameterName) ) {
statementBuilder.append(parameterName + " = ? AND");
valueList.add(parameterValues.get(parameterName));
}
}
PreparedStatement st = conn.prepareStatement(statementBuilder.toString(),
valueList);
//set each parameter here.
It's only hard the first time; then you can make it generic. That said there are probably query builders that abstract all of this away for you. I use QueryDSL but that does not have bindings for pure JDBC but rather JPA and JDO, etc.
On another forum I was given a different, simpler and cleaner approach that work perfectly.
Here are some links for others with the same problem:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1669972300346534908
http://www.akadia.com/services/dyn_modify_where_clause.html

What is wrong with this GeoTools FeatureId?

Using the GeoTools WFS-T plugin, I have created a new row, and after a commit, I have a FeatureId whos .getId() returns an ugly string that looks something like this:
newmy_database:my_table.9223372036854775807
Aside from the fact that the word "new" at the beginning of "my_database" is a surprise, the number in no way reflects the primary key of the new row (which in this case is "23"). Fair enough, I thought this may be some internal numbering system. However, now I want a foreign key in another table to get the primary key of the new row in this one, and I'm not sure how to get the value from this FID. Some places suggest that you can use an FID in a query like this:
Filter filter = filterFactory.id(Collections.singleton(fid));
Query query = new Query(tableName, filter);
SimpleFeatureCollection features = simpleFeatureSource.getFeatures(query);
But this fails at parsing the FID, at the underscore of all places! That underscore was there when the row was created (I had to pass "my_database:my_table" as the table to add the row to).
I'm sure that either there is something wrong with the id, or I'm using it incorrectly somehow. Can anyone shed any light?
It appears as if a couple things are going wrong - and perhaps a bug report is needed.
The FeatureId with "new" at the beginning is a temporary id; that should be replaced with the real result once commit has been called.
There are a number of way to be aware of this:
1) You can listen for a BatchFeatureEvent; this offers the information on "temp id" -> "wfs id"
2) Internally this information is parsed from the Transaction Result returned from your WFS. The result is saved in the WFSTransactionState for you to access. This was before BatchFeatureEvent was invented.
Transaction transaction = new transaction("insert");
try {
SimpleFeatureStore featureStore =
(SimpleFeatureStore) wfs.getFeatureSource( typeName );
featureStore.setTransaction( transaction );
featureStore.addFeatures( DataUtilities.collection( feature ) );
transaction.commit();
// get the final feature id
WFSTransactionState wfsts = (WFSTransactionState) transaction.getState(wfs);
// In this example there is only one fid. Get it.
String result = wfsts.getFids( typeName )[0];
}
finally {
transaction.close();
}
I have updated the documentation with the above example:
http://docs.geotools.org/latest/userguide/library/data/wfs.html

Categories