Synchronizing tasks and sub-tasks, while keeping the parent-child relationship on the remote side is a common use case which is possible to implement using Exalate.

On the data filter, you would send to the other side which is the parent Id of the subtask issue, if any:

Source side

Outgoing sync(Data filter):

replica.parentId = issue.parentId
 


On the receiving side, you would use that remote parent Id, to find the appropriate local parent id:

Destination side

Outgoing sync (Create/Change processor)

if(replica.parentId){
	def localParent = nodeHelper.getLocalIssueFromRemoteId(replica.parentId.toLong())
	if(localParent){
		issue.parentId = localParent.id
	} 
}

To sync the parent link together with a subtask you need to sync a parent task first, then only related sub-tasks.

In case you sync subtask before the parent task, the link to the parent will be synced on the next update of the subtask.