Skip to content
This repository was archived by the owner on Jan 19, 2022. It is now read-only.
This repository was archived by the owner on Jan 19, 2022. It is now read-only.

DatastoreTemplate or Repository does not fetch SubChild Descendants (Multiple parent keys not supported) #2503

Open
@sanveer-osahan

Description

@sanveer-osahan

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3awaitingwaiting for something externaldatastoreGCP Datastore

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions