Predicate implementation inquiry FilreredRowSet in JAVA - java

I have the following predicate implementation:
public boolean evaluate(RowSet rowset )
{try{
int count=0;
CachedRowSet crs = (CachedRowSet)rowset;
{
if (!crs.isAfterLast())//CRUCIAL LINE
for (int i=0;i<index.length;i++)
{
if ((crs.getObject(index[i])).toString().compareTo(high[i].toString())<=0)
{
if ((crs.getObject(index[i])).toString().compareTo(low[i].toString())>=0)
{
count++;
}
}
}
}
Now, if I comment out the "crucial line" hence:
if (!crs.isAfterLast())
I will get a java.sql.SQLException: Invalid cursor position.
Why does it happen so? Does not it get used the .next() method returning false if the next line is afterLast?
I can traverse any resultset without having to check if (!crs.isAfterLast()). Just using rs.next() would be enough as it returns false if next is after the last.
Why in predicate this does not happen? Thanks in advance.

The issue you are encountering is a bug in Java 7 (even in 7.0_45), documented here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7166598
A simple workaround to avoid the "Invalid cursor position" SQLException that worked for me is to add this logic to the start of your implementation of Predicate.evaluate(RowSet rs) to detect the end-of-rowset condition:
FilteredRowSet frs = (FilteredRowSet) rs;
int rowNum = frs.getRow();
if (rowNum == 0) { // Meaning "no current row" - should never happen...
return false; // Needed only to address a bug in Java 7
}
Your workaround of calling isAfterLast() also seems fine, and the ugly workaround of simply swallowing the SQLException also works, since the exception occurs after all processing is complete.
The problem is fixed under Java 8 RTE, and recompilation is not necessary.
I have specifically tested a Predicate implementation which is failing under Java 7 using Java 8, within Intellij Idea, and also from the command line. Under Java 8 it also works fine without needing the Java 7 workaround described above.

Related

Vert.x queryStream seems to hang at about 4950 rows

I am troubleshooting a strange issue with Vertx 3. I've created a request handler for an HTTP route, which queries a PostgreSQL database. It's all very standard and it works, until the row count increases beyond 4950. This is despite using queryStream, which is supposed to scale.
I've simplified the code below to illustrate the problem:
dbClient.getConnection(res -> {
if (res.failed()) {
event.fail(500);
return;
}
try (final SQLConnection conn = res.result()) {
conn.queryStream("select x, y, z from large_table", stream -> {
if (stream.succeeded()) {
final SQLRowStream rowStream = stream.result();
rowStream.handler(row -> {
// Do something with row here, but leaving it empty now
}).endHandler(endHandler -> {
response.end();
});
}
});
}
How do I go about troubleshooting this? When I run the query in psql or using regular JDBC in Java SE it has no issues.
If I append "LIMIT 4000" to the query, it works fine.
Or have I misunderstood Vertx's JDBC support, in that I have to execute this as blocking code because it is taking so long?
It seems like upgrading to vert.x 3.5.2 solved the issue. I am not sure what the actual root cause was.

Couchbase Java API not returning values for set range

I'm having a weird problem with Couchbase Java API. I use the following code:
ViewQuery query = ViewQuery.from(BUCKET_NAME, GET_ENTITIES_VIEW_NAME);
...
// set companyStart, companyEnd as Strings
// set query.limit and query.skip
...
query.startKey(toJsonArray(companyStart, Long.toString(params.getStartDate().getTime())));
endKey(toJsonArray(companyEnd, Long.toString(params.getEndDate().getTime())));
ViewResult results;
results = bucket.query(query);
...
When I try the said start and endKeys (like ["ROTOR", 146538100000]) in the Couchbase console, the query returns all the expected results.
However, with the Java API the results is empty.
If I comment out the query.startKey and .endKey lines, it faithfully returns all the results for the view.
Here's my view:
function (doc, meta) {
if(doc.collectorData.documenttypes.terms[0] && doc.collectorData.documenttypes.terms[0]=='EAP:Article') {
emit([doc.collectorData.userdata.company,doc.timestamp], {"visitId":doc.visitId,"visitorId":doc.visitorId,"company":doc.collectorData.userdata.company,"timestamp":doc.timestamp, "userAgent":doc.userAgent, "pathInfo":doc.pathInfo, "channel":doc.collectorData.channel, "newVisit":doc.newVisit});
}
}
Any tips on what may be wrong?
You are using Long.toString, so it is not equivalent to what you used in the couchbase console.
That would be equivalent to ["ROTOR", "146538100000"]. A subtle but meaningful difference!
Try with the following snippet instead (I explicitly used JsonArray.from as well, just to remove any ambiguity):
query
.startKey(JsonArray.from(companyStart, params.getStartDate().getTime()))
.endKey(JsonArray.from(companyEnd, params.getEndDate().getTime()));
Simon's tips were most helpful. The mystery had a simple solution: I forgot to publish the view, and the old view only had one-field key, so the query was executing successfully yet returning nothing! A comment somewhere through the thread on https://forums.couchbase.com/t/not-able-to-get-all-rows-returned-from-couchbase-view/5020/23 provided the enlightenment.

IllegalArgumentException: Invalid conditional statement inside expectation block

I have a problem with an Expectations block I have written in my test case:
new Expectations() {
{
mFindHandlerMock.findAll((Model) any, (Set<Id>) any, false);
if (!pWithRealData) {
result = Collections.emptySet();
} else {
result = pAllData;
}
times = 1;
Deencapsulation.invoke(mDb, "readSqlQuery", withAny(String.class));
result = "select * from realdata";
times = 1;
}
};
the test case crashes with:
java.lang.IllegalArgumentException: Invalid conditional statement inside expectation block
exactly here:
if (!pWithRealData) {
it's just a simple boolean that is false in this case.
I have absolutly no clue why the exception happens.
I already searched with google but found nothing helpful.
Could you help me?
From the JMockit release notes for version 1.14:
Enhancement: Conditionals and loops will now trigger an exception when found inside an expectation recording block, to prevent API misuse and to encourage simpler tests. See issue #97.
The GitHub issues related to this:
https://github.com/jmockit/jmockit1/issues/97
https://github.com/jmockit/jmockit1/issues/123
In the one issue they state that:
Yes, and this is as intended, to avoid tests getting too complicated when recording expectations. A full test was not shown, but it looks to me that recording the specific expectations directly would be better in this case.
In the JMockit source you can see which other types of conditionals and loops will throw that exception.
In short, from JMockit 1.14 onwards you are not allowed to have conditionals (such as if statements) and loops in the Expectation block.

Java If -else statement not working as expected

So I'm making a program on a pretty low level of Java-programming.
This is what I'm having problems with:
//The String fillText is given a value earlier in the program
if ("".equals(txa1.getText()))
{
txa1.setText(fillText);
txa1.setVisible(true);
}
else if ("".equals(txa2.getText()))
{
txa2.setText(fillText);
txa2.setVisible(true);
}
else if ("".equals(txa3.getText()))
{
txa3.setText(fillText);
txa3.setVisible(true);
}
else if ("".equals(txa4.getText()))
{
txa4.setText(fillText);
txa4.setVisible(true);
}
else if ("".equals(txa5.getText()))
{
txa5.setText(fillText);
txa5.setVisible(true);
}
...
This code appears to ALWAYS fill all of the textareas (txaX) with fillText.
I was expecting it to only execute the first of the statements that returned true and then break out of the if-else-statement.
I tried to do it with a switch-case, but ended up failing since the String is changed during the run of the program.
What is wrong?
Thanks in advance!
It is in loop .Definetely that is causing the problem.With out loop it will go to only one block.It is not possible too execute without loop.When ever we are using if else only one block will execute.
"".equals(txa1.getText())
I think above condition for each returns true.
getText() method is always returning empty string i.e "";
You have to carefully examine your conditions, it'll basically execute the predecessors if the condition is false.
I suggest you think more on the logic of what you are trying to achieve..

Java/Oracle: executing a prepared statement fails on a second iteration of a loop (not all variables bound). Why?

I'm debugging a Java App, which connects to Oracle DB via a thin client.
The code looks as follows: (i'm trying to simplify the use case here so pardon me if t does not actually comile)
Connection conn = myEnv.getDbConnection();
CallableStatement call = conn.prepareCall(
"{ ? = call SomePackage.SomeFunction (?)}");
call.registerOutParameter(1, OracleTypes.CURSOR);
for (int runCount = 0; runCount <= 1; runCount++) {
currency = getCurrency(runCount); // NOTE: [0]=CAD, [1]=USD
call.setString(2, currency);
try { call.execute(); } catch { // BREAKS HERE! }
ResultSet rset = (ResultSet)call.getObject(1);
... more code that I think is irrelevant as it does not use/affect "call"
}
When I run this code, the following happens:
First iteration of the loop, currency is set to "CAN".
Entire code of the loop runs perfectly fine.
Second iteration of the loop,currency is set to "USD".
The "execute()" call throws SQLException, as follows:
ORA-01008: not all variables bound
Why?
My initial suspicion was that it somehow related to registerOutParameter call before the loop that doesn't get called on 2d iteration. But moving that call inside the loop does not fix the problem. It seems that execute() call un-binds something but having both bindings inside the loop does not help.
What am I missing?
If it's something obvious, please be gendle - I know very little about Oracle and thin client, and Googling witrh miriad of fancy queries returned no love.
One additional clue: this design seemed to have worked before when the app was on Oracle 9 with OCI drivers. The reason I'm debuggin it is someone "upgraded" it to Oracle 10.2 thi client and it broke.
My next step should probably be bringing in entire CallableStatement into the loop, but that kind of defeats the whole idea of why I though prepared statements are used in the first place, no?
Have you tried adding call.clearParameters() into the loop? Perhaps it would reset some internal state on the object that it needs to execute again.
The explanation obtained via Oracle Support call was that this version of Java (1.3) was not compatible with new Oracle. Java 1.4 fixed the issue.

Categories