jena icon indicating copy to clipboard operation
jena copied to clipboard

"Attempt to assign an expression again" Error in nested WhereBuilders

Open arianpotter opened this issue 9 months ago • 6 comments

Version

5.3.0

Question

Dear Community Members, As a part of the project that I am working on now, I have to create dynamic SPARQL queries. To this end, I am using Jena's ARQ library QueryBuilder. The issue that I am facing now is that I need to be able to nest WhereBuilders into each other with FILTER EXISTS and I have a function like below that adds a WhereBuilder to another as FILTER EXISTS:

` private void addFilterExists(WhereBuilder outerBuilder, WhereBuilder innerBuilder) { Element innerElement = innerBuilder.build().getQueryPattern();

    ElementGroup group = new ElementGroup();
    group.addElement(innerElement);

    Expr notExistsExpr = new E_Exists(group);

    outerBuilder.addFilter(notExistsExpr);
}

` This works fine if I use it once. But if I have to nest the query again with this function into another WhereBuilder, and there is a BIND clause somewhere in the inner query, I get the error "Attempt to assign an expression again". I can not remove BIND clauses as they are getting added dynamically and are important. On the other hand, I believe the issue arises from the fact that I have to build the inner query, and when I put this built query into another whereclause and then this whereclause gets built as the inner query of another clause I get this Error while doing: Expr notExistsExpr = new E_Exists(group); Also, not building the inner query is not an option because trying to nest these without building(with WhereHandler) leads to a NullPointer exception Error.

I really appreciate any help or workaround if it is possible, as I am getting frustrated with this issue and have not found a solution so far.

arianpotter avatar May 23 '25 18:05 arianpotter

Hi @arianpotter -- could you make a concrete example? (i.e something runnable that illustrates the problem) "Details matter" when it comes to what is and is not allowed.

afs avatar May 25 '25 15:05 afs

Hi @arianpotter,

It could be what you are trying is not a legal query. If you have an complete example, we can look at it.

afs avatar Jun 07 '25 13:06 afs

Hi @afs Sorry for the late response, and thank you for your reply! It is a bit hard since this is a complex and dynamic query builder software, but an example could be like this: Let's say we have a WhereBuilder called wb1 and it contains this where clause:

WHERE{
   ?s ex:property ?o .
    BIND(?o AS ?var)
}

now, if I have another WhereBuilder called wb2 and it just contains something like:

WHERE{
   ?subject ex:path ?anotherSubject
}

And I use the function that I mentioned, like: addFilterExists(wb2,wb1) And then if I again further in my program have another simple WhereBuilder, even without any bindings like :

wb3 = 
WHERE{
  ?person ex:knows ?anotherPerson
}

And then I want to call addFilterExists(wb3,wb2), I get the error that I mentioned in this line: Expr notExistsExpr = new E_Exists(group);

Based on what I understood so far, this is due to building the query (the line in the function that builds the innerBuilder) and this gets added to another WhereBuilder (wb1 gets added to wb2) and then wb2 as the innerBuilder gets build again (when adding wb2 to wb3) and I get the error.

For the time being, my workaround is not to have any bindings at all and save them all to get added at the very end after I build my WhereBuilder with all of the nested WhereBuilders in it.

arianpotter avatar Jun 07 '25 18:06 arianpotter

Probably, you are reusing a variable name in a way that isn't allowed. But without details, i.e. code, it is hard to say why.

What is the query are you trying to build? A stack trace would be helpful.

afs avatar Jun 08 '25 13:06 afs

Probably, you are reusing a variable name in a way that isn't allowed

@arianpotter - did you resolve this at your end?

afs avatar Jul 17 '25 08:07 afs

Hi, No, as I said, I am using another approach to avoid building a wherebuilder containing a BIND clause multiple times. I am not reusing any variable. As I mentioned in my last comment, even when you have only one BIND clause and you build the where builder that contains that, and then the same where builder gets built as a part of another where builder, for some reason, Jena tries to clone the bindings in its mappings, and then it causes the error. So now I simply avoid rebuilding a wherebuilder that contains a BIND clause.

arianpotter avatar Jul 29 '25 08:07 arianpotter