Skip to content

Conversation

N-Olbert
Copy link
Contributor

Summary of the changes (Less than 80 chars)

  • Adjust result builder to not return incomplete data from the entity store
  • Detail 2

Closes #5256 (in this specific format)
Closes #8290
Probably also #5477

Background:
It was possible that Strawberry Shake returned incomplete data from the entity store when an entity referenced itself but each reference had a different selection set.

For example, consider this query:

query GetSelfishGuy {
  selfishGuy { # returns a Person!
    id # e.g. "1"
    firstName
    lastName
    bestFriend { # returns a Person!
      firstName
      age
      phone
    }
  }
}

Since the person is selfish, its best friend is him-/herself.
Because the entity store is filled recursively, the bestFriend selection set is evaluated first, writing firstName, age, and phone to the entity store for id "1". However, after that the selfishGuy selection set is evaluated and overwrites the entity store entry for "1" with the values of id, firstName, lastName, and the bestFriend-id. As a result age and phone are lost.

This PR fixes the issue by rechecking whether the entity is already present in the store after evaluating the arguments required to create the entity at the current hierarchy level. Therefore, no fields are lost and the entity store is filled correctly. In fact, it is populated step-by-step.

Core change (the args were inlined before):

 if (session.CurrentSnapshot.TryGetEntity(entityId, out global::StrawberryShake.CodeGeneration.CSharp.Integration.RecursiveEntitySelfReference.State.PersonEntity? entity))
 {
     var arg0 = Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id"));
     var arg1 = Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "firstName"));
     var arg2 = Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "lastName"));
     var arg3 = Update_NonNullableIGetSelfishGuy_SelfishGuy_BestFriendEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "bestFriend"), entityIds);
     var arg4 = Update_IGetSelfishGuy_SelfishGuy_FriendsEntityNonNullableArray(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "friends"), entityIds);
     session.SetEntity(entityId, new global::StrawberryShake.CodeGeneration.CSharp.Integration.RecursiveEntitySelfReference.State.PersonEntity(arg0, arg1, arg2, arg3, arg4, entity.Age, entity.Phone, entity.ZipCode));
 }
 else
 {
     var arg0 = Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "id"));
     var arg1 = Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "firstName"));
     var arg2 = Deserialize_NonNullableString(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "lastName"));
     var arg3 = Update_NonNullableIGetSelfishGuy_SelfishGuy_BestFriendEntity(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "bestFriend"), entityIds);
     var arg4 = Update_IGetSelfishGuy_SelfishGuy_FriendsEntityNonNullableArray(session, global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "friends"), entityIds);
+    // Since arg3 or arg 4 may have changed the entity store, check again if the requested
+    // entity now exists (and if so, us it to merge the values like age, phone etc.)
+     if (session.CurrentSnapshot.TryGetEntity(entityId, out entity))
+     {
+         session.SetEntity(entityId, new global::StrawberryShake.CodeGeneration.CSharp.Integration.RecursiveEntitySelfReference.State.PersonEntity(arg0, arg1, arg2, arg3, arg4, entity.Age, entity.Phone, entity.ZipCode));
+     }
+     else
+     {
         session.SetEntity(entityId, new global::StrawberryShake.CodeGeneration.CSharp.Integration.RecursiveEntitySelfReference.State.PersonEntity(arg0, arg1, arg2, arg3, arg4, default !, default !, default !));
+     }
  }

@michaelstaib michaelstaib marked this pull request as draft August 28, 2025 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant