As @Joshua Taylor points out in his comment, the cause is that Sesame and Jena use a different interpretation of default graph.
In Sesame, the entire repository is considered the default graph: all statements in all named graphs as well as all statements without a named graph. Therefore, the first argument of your union, which queries the default graph, succeeds and binds ?s
, ?p
and ?o
(but not ?g
). The second argument of your union obviously succeeds as well because the original quad is of course in a named graph, and therefore you get two answers.
Jena uses an "exclusive" default graph by default: only statements that are not explicitly added to any particular named graph are in the default graph. Therefore, in Jena, the first part of your union fails (there are no matching statements in Jena's default graph), the second part succeeds, and you therefore only get 1 result.
Strange as it may sound, both are correct. The difference is simply in how the dataset on which the query is executed is set up.
Of course, there are ways to deal with this. In both Jena and Sesame, you can add FROM (NAMED)
clauses to make it explicit what the queried dataset is (Sesame offers the sesame:nil
graph name to explicitly query those statements that have no named graph associated). Alternatively, you can programmatically modify the dataset definition on which a query is executed. The precise mechanisms in Jena and Sesame are a bit different, but they both have the option (in Sesame, you can create and supply a Dataset
object with your query before executing, in Jena I believe you can reconfigure the actual store or model on which you execute the query to behave differently).