Updating values in blank nodes creates an additional orphaned blank node with the old value

33 views
Skip to first unread message

Michael Panzer

unread,
Oct 14, 2025, 5:10:42 PM (9 days ago) Oct 14
to TopBraid Suite Users
When updating a blank node through a GraphQL mutation, the following happens: 

image.png
It seems that the blank node get deleted, the updated blank node gets committed, but then also the old blank node either survives or gets rewritten into the triple store as an orphan.

Is that something that might be a bug in the GraphQL engine in TopBraid or do we need to add some garbage collection cleanup to manually delete these every time a blank node value gets updated?

Holger Knublauch

unread,
Oct 14, 2025, 8:15:02 PM (8 days ago) Oct 14
to topbrai...@googlegroups.com
Hi Michael,

can you share the UPDATE that you are running here? It’s difficult to analyze with the currently provided details.

Regards,
Holger


On Oct 15, 2025, at 07:10, Michael Panzer <michael...@gmail.com> wrote:

When updating a blank node through a GraphQL mutation, the following happens: 

<image.png>
It seems that the blank node get deleted, the updated blank node gets committed, but then also the old blank node either survives or gets rewritten into the triple store as an orphan.

Is that something that might be a bug in the GraphQL engine in TopBraid or do we need to add some garbage collection cleanup to manually delete these every time a blank node value gets updated?

--
The topics of this mailing list include TopBraid EDG and related technologies such as SHACL.
To post to this group, send email to topbrai...@googlegroups.com
---
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/topbraid-users/ae40a76b-90f3-469b-906a-3548fd5558a5n%40googlegroups.com.
<image.png>

Michael Panzer

unread,
Oct 15, 2025, 12:39:24 PM (8 days ago) Oct 15
to TopBraid Suite Users
Sure, this is the full mutation, but we reproduced this with just the bnode update. 
 

mutation updateExpressionById(
   $uri: ID!,
   $primaryId:String!,
   $versionTag:String!,
   $catalogedOn: String!,
   $createdOn: String!,
   $name: String!,
   $internalName: String!,
   $state: ID!,
   $contentModel: ID!,
   $clientTag: String!,
   $tagType: ID!) {
   outcome: updateExpression (input:{
       uri:$uri                   
       internalName: $internalName
       primaryId: $primaryId
       versionTag: $versionTag
       name:{
           string:$name
           lang:"en-US"
       }
       state: {
           uri: $state
       }
       contentModel: {
           uri: $contentModel
       }
       versionCode: {
           code:$clientTag
           tagType: {uri: $tagType}
       }
       catalogedOn: $catalogedOn
       createdOn: $createdOn
   }),
   report{
       addedCount
       diff
       conforms
       results{
           message
           severity
           constraintComponentName
           pathLabel
           focusNode{
               uri
           }
           sourceShape {
               uri
           }
       }
   }
   commit(strict: true)
}

But it's really an UPDATE mutation where you have a URI, a property, and a BNode object. If you call it twice with 2 different values for the BNode, the first call creates the graphlet

URI <prop> _BNode(val1)
 
the second call updates the property

URI <prop> _BNode(val2)

but does not delete _BNode(val1) from the graph in the process

Holger Knublauch

unread,
Oct 15, 2025, 10:23:42 PM (7 days ago) Oct 15
to topbrai...@googlegroups.com
Hi Michael,

Thanks for the details. I first thought it was a SPARQL-based mutation, but you’re using updateXY.

I checked the source code and don’t see that we have special intelligence to handle blank nodes here.

One tricky bit is that it is unclear if these updates should modify the already existing blank node or rather create a new one. If it’s supposed to create a new one then that would need to have all values for the properties, while an incremental update would only require the replacement values.

So I am afraid this clean-up is not supported with the GraphQL update operation. It will always just create a new blank node.

The alternative would be to formulate these updates as SPARQL INSERT/DELETE and then either use the SPARQL endpoint or the sparql field in GraphQL mutations.

Is this an option for you, or do you have specific reasons for using GraphQL here?

Holger


Davide Sottara

unread,
Oct 16, 2025, 3:09:13 PM (7 days ago) Oct 16
to TopBraid Suite Users
Hi Holger, 

let me add some details
We are using GraphQL queries, maintained client-side, because the clients are familiar with GraphQL but not with SPARQL,
so we are trying to avoid using SPARQL if possible

We also have a workaround for the time being: just before using the 'update' mutation, we 'get' the state of the graph.
We can pull the URI of the BNode, and combine 'deleteValue' with the 'updateX' mutation.
(Would you have any other pure-GraphQL ideas?)

In principle, we are using the BNode to implement a structured Datatype, and/or consider the underlying property 
as a datatypeproperty. With a 'value' type, one normally always sets all the elements, and deleting the BNode to replace it,
vs reusing the existing, would be the same.

Do you think something like this could be feasible?

Thank you!
Davide

Holger Knublauch

unread,
Oct 16, 2025, 10:55:50 PM (6 days ago) Oct 16
to topbrai...@googlegroups.com
A change to the treatment of blank nodes in our GraphQL engine will require server-side changes. Assuming this gets into our todo list, it would take until 9.1 at the earliest to make these changes, as 9.0 is just being published this week. Could you file an enhancement request through our ticketing system to get the ball rolling?

Meanwhile, using URI nodes would be the only work-around.

Holger


Reply all
Reply to author
Forward
0 new messages