[ https://issues.apache.org/jira/browse/JENA-1841?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17049652#comment-17049652 ]
Claude Warren edited comment on JENA-1841 at 3/2/20 10:38 PM: -------------------------------------------------------------- When creating a Node from an Object the QueryBuilder code does the following: convert _null_ to {{Node.ANY}} if object instance of {{FrontsNode}} check if var and return {{Var.alloc( node )}} or node if not var. if object instance of {{Node}} check if var and return {{Var.alloc( node )}} or node if not var. if object instance of String call {{NodeFactoryExtra.parseNode( string, prefixmap )}} then check for var as above. If this throws a RiotException ignore it and attempt the next conversion all other cases, call {{NodeFactory.createLiteral( LiteralLabelFactory.createTypedLiteral( object ) )}}. So in the case of a UUID object it will call {{LiteralLabelFactory.createTypedLiteral( uuid )}} which will eventually call {{TypeMapper.getTypeByValue( uuid )}}. If that returns null it will "invent a datatype", otherwise it will use the RDFDatatype. In the ExprFactory {{eq( object, object )}} does the following conversions: if object is null return {{Expr.NONE}} if object is instance of {{Expr}} return {{(Expr)object}} otherwise convert to {{Node}} using above process. If node is Var return {{ExprVar( Var )}} otherwise call {{NodeValue.makeNode( node )}}. Given the {{eq( "?uuid", uuid )}} the toNodeValue will be passed the literal node as created by {{LiteralLabelFactory.createTypedLiteral( uuid )}} So if {{NodeValue.nodeToValue( NodeFactory.createLiteral( LiteralLabelFactory.createTypedLiteral( uuid ) ) )}} returns what you are expecting the query builder will work. Andy's solution of registering a new type should work as expected. was (Author: claudenw): When creating a Node from an Object the QueryBuilder code does the following: convert _null_ to {{Node.ANY}} if object instance of {{FrontsNode}} check if var and return {{Var.alloc( node )}} or node if not var. if object instance of {{Node}} check if var and return {{Var.alloc( node )}} or node if not var. if object instance of String call {{NodeFactoryExtra.parseNode( string, prefixmap )}} then check for var as above. If this throws a RiotException ignore it and attempt the next conversion all other cases, call {{NodeFactory.createLiteral( LiteralLabelFactory.createTypedLiteral( object ) )}}. So in the case of a UUID object it will call {{LiteralLabelFactory.createTypedLiteral( uuid )}} which will eventually call {{TypeMapper.getTypeByValue( uuid )}}. If that returns null it will "invent a datatype", otherwise it will use the RDFDatatype. In the ExprFactory {{eq( object, object )}} does the following conversions: if object is null return {{Expr.NONE}} if object is instance of {{Expr}} return {{(Expr)object}} otherwise convert to {{Node}} using above process. If node is Var return {{ExprVar( Var )}} otherwise call {{NodeValue.makeNode( node )}}. Given the {{eq( "?uuid", uuid )}} the toNodeValue will be passed the literal node as created by {{LiteralLabelFactory.createTypedLiteral( uuid )}} So if {{NodeValue.nodeToValue( NodeFactory.createLiteral( LiteralLabelFactory.createTypedLiteral( uuid ) ) )}} returns what you are expecting the query builder will work. Andy's solution of registering a new type should work as expected. > Side Effect of Datatype <java:java.util.UUID> Use in Query > ---------------------------------------------------------- > > Key: JENA-1841 > URL: https://issues.apache.org/jira/browse/JENA-1841 > Project: Apache Jena > Issue Type: Bug > Affects Versions: Jena 3.14.0 > Reporter: Jan Martin Keil > Priority: Major > > I faced a bug caused by a side effect of using the datatype > <java:java.util.UUID> in a query. > Short story is that you can not use this datatype in model parsing or queries > after you once used it in a query. > I did not completely break it down to a specific peace of code, but I wrote > some testcases that narrow down the issue. Please note that the order of > execution of the test methods effect the result. So please first try to > execute single test methods before executing the whole test class. > {code:java} > import java.io.ByteArrayInputStream; > import java.util.UUID; > import org.apache.jena.arq.querybuilder.SelectBuilder; > import org.apache.jena.query.QueryExecution; > import org.apache.jena.query.QueryExecutionFactory; > import org.apache.jena.rdf.model.Model; > import org.apache.jena.rdf.model.ModelFactory; > import org.junit.jupiter.api.Test; > public class UuidParsingintoModelOrQuery { > @Test > public void uuidParsingIntoSingleModel() throws Exception { > UUID uuid1 = > UUID.fromString("00000000-0000-0000-0000-000000000000"); > UUID uuid2 = > UUID.fromString("00000000-0000-0000-0000-000000000001"); > String modelStr = "_:a <http://example.org/p1> \"" + uuid1 + > "\"^^<java:java.util.UUID> .\n" > + "_:a <http://example.org/p2> \"" + uuid1 + > "\"^^<java:java.util.UUID> ."; > ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", "N-TRIPLE"); > // repeat > modelStr = "_:a <http://example.org/p1> \"" + uuid2 + > "\"^^<java:java.util.UUID> .\n" > + "_:a <http://example.org/p2> \"" + uuid2 + > "\"^^<java:java.util.UUID> ."; > ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", "N-TRIPLE"); > } > @Test > public void sameUuidParsingIntoSingleModel() throws Exception { > UUID uuid1 = > UUID.fromString("00000000-0000-0000-0000-000000000002"); > UUID uuid2 = > UUID.fromString("00000000-0000-0000-0000-000000000003"); > String modelStr = "_:a <http://example.org/p1> \"" + uuid1 + > "\"^^<java:java.util.UUID> .\n" > + "_:a <http://example.org/p2> \"" + uuid2 + > "\"^^<java:java.util.UUID> ."; > ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", "N-TRIPLE"); > // repeat > ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", "N-TRIPLE"); > } > @Test > public void sameUuidParsingIntoMultipleModel() throws Exception { > UUID uuid = > UUID.fromString("00000000-0000-0000-0000-000000000004"); > String modelStr = "_:a <http://example.org/p1> \"" + uuid + > "\"^^<java:java.util.UUID> ."; > ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", "N-TRIPLE"); > ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", "N-TRIPLE"); > } > @Test > public void uuidUseInQuery() throws Exception { > UUID uuid = > UUID.fromString("00000000-0000-0000-0000-000000000005"); > SelectBuilder select = new SelectBuilder(); > select.addWhere("?a", "<http://example.org/p>", "?uuid"); > select.addFilter(select.getExprFactory().eq("?uuid", uuid)); > QueryExecution q = QueryExecutionFactory.create(select.build()); > } > @Test > public void uuidParsingIntoQuery() throws Exception { > UUID uuid = > UUID.fromString("00000000-0000-0000-0000-000000000006"); > SelectBuilder select = new SelectBuilder(); > select.addWhere("?a", "<http://example.org/p>", "?uuid"); > select.addFilter(select.getExprFactory().eq("?uuid", uuid)); > QueryExecution q = > QueryExecutionFactory.create(select.toString()); > } > @Test > public void uuidUseInQueryAndParsingIntoModel() throws Exception { > UUID uuid = > UUID.fromString("00000000-0000-0000-0000-000000000007"); > SelectBuilder select = new SelectBuilder(); > select.addWhere("?a", "<http://example.org/p>", "?uuid"); > select.addFilter(select.getExprFactory().eq("?uuid", uuid)); > QueryExecution q = QueryExecutionFactory.create(select.build()); > String modelStr = "_:a <http://example.org/p1> \"" + uuid + > "\"^^<java:java.util.UUID> .\n" > + "_:a <http://example.org/p2> \"" + uuid + > "\"^^<java:java.util.UUID> ."; > Model model = ModelFactory.createDefaultModel().read(new > ByteArrayInputStream(modelStr.getBytes()), "", > "N-TRIPLE"); > } > } > {code} -- This message was sent by Atlassian Jira (v8.3.4#803005)