If a save operation fails then the client side state will still be either "added", "modified" or "deleted". Changes are only accepted if a save succeeds. This allows you to "resave" the same entity or entities after you have "corrected" the issue without having to reassemble the changes.
You can also use Breeze EntityAspect.rejectChanges to return an entity to its state when it was last queried.
The simplest way to copy an entity is to use the Breeze EntityManager.createEntity method and pass in an object that contains just the data properties from the source entity. The reason this will work is that Breeze will automatically link up all of the navigation properties for you based on the foreign key data properties once the new entity is attached to the entityManager, which occurs internally as the last step of the createEntity call.
So you might try something like this ( I didn't actually test this code fragment but this approach definitely does work.
function cloneEntity(sourceEntity, keyName, newKeyValue) {
var sourceEntityType = sourceEntity.entityType;
var sourceDataProperties = sourceEntityType.dataProperties;
var configEntity = {};
sourceDataProperties.forEach(function(dp) {
configEntity[dp.name] = sourceEntity.getProperty(dp.name);
});
// you will need to give the entity a unique key before calling createEntity
// you could also get the keyName from metadata but I was too lazy to do that here.
configEntity[keyName] = newKeyValue;
var cloneEntity = myEntityManager.createEntity(fooEntityType, configEntity, breeze.EntityState.Added);
return cloneEntity;
}