I have no experience with the session-per-conversation pattern, but disregarding this, it should not really matter if you call flush() or not. In the end all changes needs to be SQLed to the database and if that happens now and then or only at the end of the conversation should only have marginal effect on the performance.
The problem is I assume that each request still has it's own transaction and if you flush in a middle step the changes will be committed to the database and there is no way of rolling back this when the conversation ends. So, if you want to use the session-per-conversation pattern you should not flush until the end.
But then you also need to be aware of that queries are always executed against the database and since what is in the database may not match what is stored in the session the result may be unexpected. In the above code example you could do:
Code:
p1.getDoctor().getPeople().remove(p1);
ms.delete(p1);
But I guess in the more complex case it will be too complex to get this correct and also too demanding when it comes to future changes and code maintenance. I have no good solution for this problem. Maybe you can keep your own "cache" of items that have been deleted and then display some kind of marker icon in the web interface.
Finally, to answer the question in the original post:
Hibernate shouldn't understand that p1 is no more associated with d1?p1 is still associated with d1. It has only been marked for deletion, and as long as the deletion hasn't happened (eg. the session has been flushed) it is associated with d1.