DatastoreTemplate or Repository does not fetch SubChild Descendants (Multiple parent keys not supported) #2503
Description
I have a Parent/Child/SubChild relationship modeled as follows using @Descendants
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "parent")
public class Parent {
@Id
Long id;
@Descendants
List<Child> children;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "child")
public class Child {
@Id
Key id;
@Descendants
List<SubChild> subChildren;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "subchild")
public class SubChild {
@Id
Key id;
String someValue;
}
When you try to retrieve the parent object(s) using a DatastoreTemplate or Repository, they contain the child records but the child records do not contain subchild records.
Even if you try to recieve only the child object(s), they do not retrieve their subchild records.
Steps to Reproduce
I have created the following JUnit test to explain the issue:
@Test
void datastoreTest() {
Key parentKey = Key.newBuilder(gcpDataStoreProjectId, "parent", 1).setNamespace(gcpDataStoreNameSpace).build();
Key childKey = Key.newBuilder(parentKey, "child", 2).build();
Key subChildKey = Key.newBuilder(childKey, "subchild", 3).build();
SubChild subChild = new SubChild(subChildKey, "someValue");
Child child = new Child(childKey, Arrays.asList(subChild));
Parent parent = new Parent(1L, Arrays.asList(child));
datastoreTemplate.save(parent);
Assertions.assertEquals(parent, datastoreTemplate.findById(parent.getId(), Parent.class));
}
Expected Result
The assertion should pass as we are trying to fetch the same entity object which was saved.
Actual Result
The assertion fails as the fetched entity doesn't retrieve the subchild record(s).
Additional Steps
System.out.println(datastoreTemplate.findById(parent.getId(), Parent.class));
System.out.println(datastoreTemplate.findById(child.getId(), Child.class));
System.out.println(datastoreTemplate.findById(subChild.getId(), SubChild.class));
Parent(id=1, children=[Child(id=Key{projectId=projectId, namespace=default, path=[PathElement{kind=parent, id=1, name=null}, PathElement{kind=child, id=2, name=null}]}, subChildren=[])])
Child(id=Key{projectId=projectId, namespace=default, path=[PathElement{kind=parent, id=1, name=null}, PathElement{kind=child, id=2, name=null}]}, subChildren=[])
SubChild(id=Key{projectId=projectId, namespace=default, path=[PathElement{kind=parent, id=1, name=null}, PathElement{kind=child, id=2, name=null}, PathElement{kind=subchild, id=3, name=null}]}, someValue=someValue)
Current Workaround
For now, I'm using the following alternative:
Key parentKey = Key.newBuilder(gcpDataStoreProjectId, "parent", 1).setNamespace(gcpDataStoreNameSpace).build();
Key childKey = Key.newBuilder(parentKey, "child", "1#2").build();
Key childKeyForSubChild = Key.newBuilder(gcpDataStoreProjectId, "child", "1#2").setNamespace(gcpDataStoreNameSpace).build();
Key subChildKey = Key.newBuilder(childKeyForSubChild, "subchild", 3).build();
SubChild subChild = new SubChild(subChildKey, "someValue");
Child child = new Child(childKey, Arrays.asList(subChild));
Parent parent = new Parent(1L, Arrays.asList(child));
datastoreTemplate.save(parent);
System.out.println(datastoreTemplate.findById(parent.getId(), Parent.class));
Parent(id=1, children=[Child(id=Key{projectId=costoptimizationproject, namespace=test, path=[PathElement{kind=parent, id=1, name=null}, PathElement{kind=child, id=null, name=1#2}]}, subChildren=[SubChild(id=Key{projectId=costoptimizationproject, namespace=test, path=[PathElement{kind=child, id=null, name=1#2}, PathElement{kind=subchild, id=3, name=null}]}, someValue=someValue)])])
This solution fetches the children along with their subchildren because now subchild entity has only single parent key. But I'm compelled to use parentId#childId as combination for child entity id.
Can there be a support for retrieving sub-descendants with multiple parent keys?