Record passed from force:recordData to Apex controller method is null

force:recordData loads the data asynchronously. This means it won't be available in the init method. Instead, listen for a change event and then get your data:

<aura:handler name="change" value="{!v.parent}" action="{!c.loadChildData}" />

loadChildData: function(component, event, helper) {
    var action = component.get("c.queryData");
    action.setParams({ parent: component.get("v.parent") });
    action.setCallback(...);
    $A.enqueueAction(action);
}

The layout for the force:recordData object doesn't align well with the default layout, and the Locker Service Proxy tends to muck things up. Here's an example I finally got working in my org:

change: function(component, event, helper) {
    var action = component.get("c.queryData"), account = component.get("v.account"), param;
    param = { sobjectType: 'Account', Id: account.fields.Id.value, Name: account.fields.Name.value };
    action.setParams({ record: param });
    console.log(param);
    action.setCallback(this, function(result) { console.log(result.getReturnValue()); });
    $A.enqueueAction(action);
}

Okay! So Here is what you are Missing here. 1. you can not send Sobject as parameter so break it into fields that you want to use. 2.You are not using recordUpdated="{!c.doInit}" in force:recoedData That is why init works for first time and it gets null. I created custom object Property and did this. Take a look

Component :

<aura:component controller="MyCtrl" implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >

<aura:attribute name="property" type="Property__c" />

<aura:handler name="init" value="{!this}" action="{!c.doInit}" />

 <force:recordData aura:id="propertyService" 
                  recordId="{!v.recordId}"
                  targetRecord="{!v.property}"
                  recordUpdated="{!c.doInit}"
                  layoutType="FULL" />

 </aura:component>

jsController : which has a custom field named as beds__c

({
doInit : function(component, event, helper) {
   var action = component.get("c.queryData");        
   action.setParams({
        beds: component.get("v.property.fields.Beds__c.value")
   });
    action.setCallback(this, function(response) {

    });

    $A.enqueueAction(action);   
}
})

Apex Controller :

public class MyCtrl {

@AuraEnabled
public static void queryData(String prop) {

    System.debug('parent' + prop);
     // prop is not null
}
}