Has anyone else encountered "NoSuchElementException" when calling getLeafTrees() on a tree object
Did a little bit of debugging and it seems that the issue has to do with a cast to Tree before calling the isLeaf() method inside getLeafTrees(). As far as my testing goes it seems to happen when a child of the root is a leaf. Here's an example dataset and the tree query:
Data:
Query:
g.V().hasLabel("Dev").hasLabel("root").emit().until(out().count().is(0)).repeat(out()).tree().by(elementMap()).next()
The edge lables are inconsequential, i just modified a binary tree. The elementMap inside the by is also there for debug purposes.11 Replies
Also here's the stack trace:
Somehow when the "tree" object goes into isLeaf() it gets casted to a tree with no value key which returns an exception when used inside the method. At least that what i understood, i'm not amazing at debugging tbh
well, given your data and traversal it's returning an empty tree:
so in some respects i think a
NoSuchElementException
is expected. Perhaps the behavior should be different in the case of an empty tree. i'm not sure.That's odd, here's the tree that's returned with my current setup
Perhaps I messed something up when copying the dataset insertion query, I'll check it out tomorrow
This is the exact line i use inside my application
The insertion seems fine, i'm not sure why the query itself wouldn't return anything for you. Was there any error thrown during either of the steps?
I'm using gremlin in Spring Boot with the java driver, connected to AWS Neptune if that matters in any way. The tree was sent on a route.
Also the tinkerpop version is 3.5.2
'gremlin': {'version': 'tinkerpop-3.5.2'}
on closer inspection, your data doesn't quite align with your query is one issue I see. i guess you are using multi-label features of Neptune. i wasn't trying on Neptune, so I guess that is part of the problem, but other tests I've done to avoid the multi-label feature haven't replicated the problem. i guess i'd have to try on Neptune.
Thanks for the response,
I forgot it was a Neptune feature, sorry about that, I added the Dev label because we only have one db and i wanted to easily dispose of the nodes after testing.
The labels shouldn't matter in the code as I don't use them for anything, my guess is that perhaps it's in the java driver. I'll try setting some breakpoints and send some screenshots of where it dies inside the method.
Oops turns out my assumptions about the structure of the tree leading to that error were wrong, it was giving a completely unrelated error. Here's a few screenshots of what happens with the big dataset i originally encountered this error on. I'll try making another dataset to get to the root of this problem. I'll post it if i succeed in finding out what the problem is
Turns out it was the query actually, I wrongfully dismissed the fact that inside the main application there was a union() step inside the by() of the tree because I assumed it gets sent as a string key for the map. I'm guessing this mashup of data structures causes undefined behaviour. Here's the modified query that results in an error:
I'll have to think of another way of gathering data from the tree, thanks for your time
Yep, the key of the tree has to be a LinkedHashMap, which isn't the case with a union step.
If anyone stumbles upon this in the future, the project step works really well as a replacement. I was using union for space efficiency on big data but it was probably premature optimization anyway.
This time I have absolutely no clue. Wish i could provide more info but i'm going crazy with this. Just tested that same query with the union on the exact same dataset and now it's working. Even worse the query with project in the main app that was working yesterday now gives the error.
All i can say unfortunately is that somehow a tree with size 0 ends up in the if statement and breaks the isLeaf() function
For the time being i'll probably just parse the tree as a string and insert it into a general graph class in java
Grasping at straws really, but it seems that the isLeaf() method is not being used correctly inside getLeafTrees() since it only checks the first branch for child nodes instead of checking all of them, thus providing a reason for the inconsistent errors (because the nodes aren't ordered in any way and get sent from the db in an arbitrary order)
Perhaps i've misunderstood what a leaf is under this definition, but under the general tree leaf definition it looks a bit wrong
Unless I'm somehow ending up with malformed trees ofc, i'll have to do more debugging
Yeah it's not the isLeaf() method itself, somehow when running getLeafTrees() there end up trees in there that have multiple roots. Maybe i misunderstood what a "leaf tree" is, can't blame myself too much for that since there's no doc. Also found this which seems pretty similar to my issue (https://github.com/JanusGraph/janusgraph/issues/1360)
Here's the code I now use to extract child trees from a root
I'd like to help but I really need a reproducible case for what you are seeing. Is that something you could provide yet?
Still working on getting some consistency with this error, it really threw me off that the last query suddenly started working the next day. I understood that getLeafTrees() is supposed to retrieve all child subtrees of the root, so if that's the case i wasn't misusing it. I suppose the method is basically those for loops i wrote with an isLeaf() check , but it's too low level for me to completely grasp and debug.
I guess for now this can be considered solved since i've found a work-around, hopefully i'll manage to get a consistent reproducible dataset.