Q:

Send user to edit page without inserting the record

I currently have an Apex class that pulls the data from a record of one custom object 'property__c' and uses it to create a record of another object 'proposal__c' and then redirects the user to this new record's edit view.
However, there's a problem with this. On the edit page, if the user hits "cancel," the record is still inserted. This is because in order to direct the user to the edit view of the new record, we have to first insert that record so that we can pull its id.
Outside of making a custom edit view for this object, is it possible to send the user to the edit view without inserting the record first? This would ideally behave the same as if the user simply hit the "new" button and then "cancel." The only difference is, we want some of the fields of the record to be pre-populated.
Here is the code. You can see where it redirects the user at the bottom of the convert method.
public class ControllerCreateProposalView {

    public Id propertyId;

    public ControllerCreateProposalView(ApexPages.StandardController stdController){
        propertyId = ApexPages.CurrentPage().getParameters().get('id');
    }

    public PageReference convert(){
        PageReference pref;

        Property__c property = [
            select 
                Id, 
                Name, 
                OwnerId, 
                Primary_Contact__c, 
            from Property__c 
            where Id = :propertyId limit 1
        ];
        Proposal__c proposal = new Proposal__c(
            Name =  property.Name, 
            OwnerId  =  property.ownerid, 
            Property__c = property.Id, 
            Client__c = property.Primary_Contact__c, 
        );

        insert proposal;

                        String sServerName = ApexPages.currentPage().getHeaders().get('Host');
        sServerName = 'https://'+sServerName+'/';
        String editName='/e?retURL=%2F'+proposal.Id;
        pref = new PageReference(sServerName + proposal.Id+editName); 
        pref.setRedirect(true);

        return pref;

    } 

    public PageReference back(){
        PageReference pref = new PageReference('/' + propertyId);
        pref.setRedirect(true);
        return pref;
    }      
}

EDIT:
I can send the user to the default edit page, which is /xxxx.salesforce.com/a0r/e?retURL=%2Fa0r%2Fo 
and I can even pass in values for standard fields, such as "name"
/xxxx.salesforce.com/a0r/e?name=TEST&retURL=%2Fa0r%2Fo 
But I cannot pass custom fields. If I could pass custom fields in using this method, I believe I could achieve what I want to do.

A:

As you've mentioned in your edit, you can pass fields in the URL
  string, but only if you use the Field ID, a concept known as
  "Salesforce URL hacking". You can read more about that if wanted on
  this other Salesforce Stack:
  How do I prepopulate fields on a Standard layout?

Keep in mind that, while it is possible to pre-populate standard and custom fields using this method, the implementation is difficult since there is no guarantee that your field IDs will be identical across different environments (sandboxes, dev orgs, production). If for example my Custom_Field__c has an ID of 00NJ00000022gx0 in my sandbox, it is not guaranteed to have that same ID in production. This could result in your custom links/buttons/logic not inserting the correct data if you accidentally overwrote a 'working' button with a button from another org with different hard coded IDs.
You could probably create a custom setting that holds all of the correct IDs for the fields in each org, and then code your button to pull from that custom setting, but depending on how many fields you're pulling it could become a burden to maintain/update. Because of this, I wouldn't recommend this approach.

Beyond that hack, I think the answer to your question is ultimately
  no. You can't edit a record until it has been committed, and you can't
  roll back the commit on cancel since it has already occurred and no
  triggers or workflows will fire on the cancel action.

As a roundabout alternative, you could consider something like this:

Create Boolean field (Default True) on Object being inserted that
you want to 'roll back'
Create WFR that sets that Boolean to FALSE (if it is currently TRUE) on successful edit of the record
Using a relatively simple scheduled Apex job, you could query every hour for all object records that still have the Boolean value set
to TRUE that were created more than an hour ago. Then delete all of
those records.

This approach wouldn't result in an instant delete when pressing cancel, but would provide for a way for the platform to 'clean' itself hour by hour to get rid of the unwanted records.

