For many actions, Hibernate generates an event that can be listened for and some support code for listening.
If you're using Spring in conjunction with Hibernate, for instance, you can register a class org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener as a listener for hibernate's merge event (from I think spring-orm.jar) by putting the following in your hibernate.cfg.xml (or whatever file is referenced in your spring setup for hibernate config):
<event type="merge">
<listener class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</event>
or by adding an map in your sessionFactory bean:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
p:dataSource-ref="dataSource">
<property name="configLocation" value="WEB-INF/classes/hibernate.cfg.xml"/>
<property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property>
If you do either of these, this listener should set the id in the original object. If you're not using Spring, there's likely a way to get a listener connected that's similar to one of these.
I haven't tested the child behavior you're looking for, but I'm pretty sure that a merge on the parent will trigger a merge on the child so that the listener will be called for both.
The setup for JPA might be different, but I suspect it's possible, and hope this gives clues.