Neo4J - Java: Result incomplete - java

I have a strange problem when I'm trying execute a cypher query in an java application.
The result.dumpToString()- method shows me the correct result.
But when I'm trying to iterate, the last node is always missing (for every executed query):
for (Map<String, Object> row : result) {
System.out.println(((Node) row.get("A")));
System.out.println(((Node) row.get("A")).getProperty("name").toString());
}
The first output is correct. I see all nodes of the result.
In the second output one node is missing, although I know, that the node has a "name"-property.
Has someone an idea?
Thank you

If you're missing a second output, it's likely that the value of that property is a string that is blank. This line:
System.out.println(((Node) row.get("A")).getProperty("name").toString());
In the presence of an attribute "name" that is blank, this will print nothing at all (but a linefeed).
Also, the way you're doing this is a bit dangerous; keep in mind that in general nodes can be missing, so getProperty("name") can return null. Meaning that when you call toString() on it, you can end up with a NullPointerException. It's better to maybe write either this:
row.get("A").getProperty("name", "missing").toString();
That will return "missing" if the property is missing, or:
Object propValue = row.get("A").getProperty("name");
if(propValue != null)
System.out.println(propValue.toString());
else System.out.println("Missing name property");

Solved my problem:
I was executing the query without beginning a Transaction.
Now it works. Nevertheless this is a strange behaviour.
Thank you all

Related

Java - IF statement treats value as NULL even though it isn't when checking in debug

This is a strange one so any help would be appreciated.
I'm working on a Spring Batch job that sends transactions to a Kafka topic and when successful the status code is returned as a String: "C". There's a check for if this status code is null and if so it will give an appropriate error message as below to be outputted onto a table later on.
if (kafkaWriter.getKafkaStatusCode() == null)
{
messagingResultCode = CommonConstants.KAFKA_NULL_RESULT;
}
So what's happening is that for several transactions that are picked up by the job I get a Kafka null result error message because of the above code so I went into debug to see what was happening putting a breakpoint at where messagingResultCode is set.
But when I evaluated "kafkaWriter.getKafkaStatusCode() == null" it showed as "(boolean) false" in Spring Tools Suite. When looking at the KafkaStatusCode it shows as "C" so definitely not null, but it still went into the code anyway.
All getKafkaStatusCode() does is return a String:
public String getKafkaStatusCode() {
return kafkaStatusCode;
}
This only ever happens on the first job that's been run on the server (I'm using Liberty) and on all subsequent runs the code behaves as expected.
I've tried initialising the String messagingResultCode to null, "" and a default value but the same thing happens every time.
Thanks
".or: (time/) asynchronity is in place ;) (I.e. debugging influences the outcome;) – xerx593 3 hours ago"
#xerx593 You were right, the debugger wasn't showing me the correct value which I found after putting in some extra logging and running it in non-debug.
Turns out you can't trust the debugger all the time :)
Thanks

How am I supposed to extract properties from a node in Apache Jackrabbit from xml?

I have been playing around with the example number three in here http://jackrabbit.apache.org/jcr/first-hops.html , however to me it remains unclear how to get access to the properties of a node.
In the first screenshot
I used the debugger from my IDE and I evaluated this expression
session.getNode("/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn").getProperty("jcr:xmltext/jcr:xmlcharacters").getString().trim();
You can see how I can get access to "jcr:xmltest/jcr:xmlcharacters" and have 2 as a result.
However, when I try to get this information, get this property out of the node, I am unable to perform this operation as in this screenshot.
This is the code fragment in the above screenshot:
var node = session.getNode("/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn");
var properties = node.getProperties();
List<string> result = new ArrayList<>();
while(properties.hasNext()) {
Property property = properties.nextProperty();
result.add(property.getString().trim());
}
return result;
You can see how I get as a response only a value containing "nt:unstructured".
Unfortunately I couldn't find many code examples online, on Github, etc. many outdated, and also, there are not books as there are for Scrapy or other libraries/frameworks.
Thank you in advance.
Have a nice day!
Davide
In the first case, you are looking at the properties of:
/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn/jcr:xmltext
In the second case:
/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn
Note the different paths.

Play 2.5: Form validation - on error, value of form is "Optional.empty"

I am developing an application with Play 2.5. Models and Form data are separate classes, so I have a class "Page" and "PageForm".
In PageForm is a method "validate()" which returns null if there was no error or a List if the validation failed:
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<>();
Page checkForDuplicatePage = PageRepository.getInstance().getByName(name);
if(checkForDuplicatePage != null && checkForDuplicatePage.id != id) {
errors.add(new ValidationError("name", "The name is already in use by another page"));
}
// ...
return errors.isEmpty() ? null : errors;
}
In my controller I call:
Form<PageForm> form = formFactory(PageForm.class).bindFromRequest();
This works really well if the data in the form is correct. However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this), the "value" attribute of my form is Optional.empty. The "data" attribute actually has all the data passed to the form.
This means I can't use the form to pass it to my view, which should display the data with error messages. Instead I get a [CompletionException: java.util.NoSuchElementException: No value present]. Sometimes (I haven't figured out why that happens yet) it also says [CompletionException: java.util.NoSuchElementException: None.get].
I compared my code with other projects and the official docs, but they all seem to be doing what I have here.
I use Scala Play rather than Java, so YMMV. But to me, I don't think that validate should return null at all. It should return the empty ArrayList if there are no errors. I suspect that this will eliminate the None.get error message. I'm not sure how much I can help, though, because I don't really understand very well what your code is intended to do. For example, the sentence
However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this)
seems kind of ambiguous to me. Where is the return new ArrayList<>() call that triggers the error?

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.

Java Enum Returns Null

I am currently creating a plugin for Minecraft using the SpigotAPI. Reason I'm posting this here is because this I believe is a Java error. I am creating a duels plugin where inside my code it'll loop through an enum, and see if it's a specific type. The first time using it around it properly works, no problems. But when I try it for a second time without restarting my plugin/program/code it'll return the enum as null. Here is the code, is there a fix to this?
public DuelArenas[] getArenasWithType(DuelTypes type) {
String suffix = "_NORMAL";
List<DuelArenas> arenasAsList = new ArrayList<>();
switch (type) {
case NORMAL:
suffix = "_NORMAL";
break;
}
for (DuelArenas arena : duelArenaStatus.keySet()) {
if (arena.toString().endsWith(suffix)) {
arenasAsList.add(arena);
}
}
DuelArenas[] arenas = new DuelArenas[arenasAsList.size()];
return arenasAsList.toArray(arenas);
}
Stacktrace:
Caused by: java.lang.NullPointerException
at me.nick.acore.duels.DuelsAPI.getArenasWithType(DuelsAPI.java:97) ~[?:?]
And yes I've checked to see if the enum was null, and it was in fact null. Also line 97 is
if (arena.toString().endsWith(suffix)) {
And finally here is the DuelArena class
public enum DuelArenas {
ARENA_1_NORMAL, ARENA_2_NORMAL, ARENA_3_NORMAL, ARENA_4_NORMAL, ARENA_5_NORMAL,
ARENA_6_NORMAL, ARENA_7_NORMAL, ARENA_8_NORMAL, ARENA_9_NORMAL, ARENA_10_NORMAL,
ARENA_11_NORMAL, ARENA_12_NORMAL }
Thanks!
Your problem is that you cannot directly convert your custom DuelArenas class to a string. However when you are comparing to see if a .toString() ends with suffix, I feel that something is also going wrong. You would only ever use .toString to convert things like numbers to strings, and if your are converting a number to a string there is no way it will end in _NORMAL.
So if you want me to troubleshoot further please post your DuelArenas class, but until then my best guess is that when you do arena.toString you are looking to pull some sort of value from that class that is stored in it, and to do this you would do arena.variableInsideArenaName and work with that.
EDIT:
After seeing the class scratch that, the error in going to be somewhere in this line DuelArenas arena : duelArenaStatus.keySet()

Categories