So, let's go with a less complex example. Two classes, Person and Address:
Code:
package test.domain;
import java.util.Collection;
public class Person {
   private long seq;
   private String name;
   private Collection addresses;
   
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public long getSeq() {
      return seq;
   }
   public void setSeq(long seq) {
      this.seq = seq;
   }
   public Collection getAddresses() {
      return addresses;
   }
   public void setAddresses(Collection addresses) {
      this.addresses = addresses;
   }
}
Code:
package test.domain;
public class Address {
   private long seq;
   private String description;
   public String getDescription() {
      return description;
   }
   public void setDescription(String description) {
      this.description = description;
   }
   public long getSeq() {
      return seq;
   }
   public void setSeq(long seq) {
      this.seq = seq;
   }
}
The mapping files:
Person.hbm.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
        <class name="test.domain.Person" table="PERSON">
                <id name="seq" column="seq" type="long">
                   <generator class="sequence">
                      <param name="sequence">TSTQ_PER</param>
                   </generator>
                </id>
                <property name="name" column="NAME"/>
             <set name="addresses" cascade="all-delete-orphan">
               <key column="PER_SEQ" not-null="true"/>
               <one-to-many class="test.domain.Address"/> 
             </set>
        </class>
</hibernate-mapping>
Address.hbm.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
        <class name="test.domain.Address" table="ADDRESS">
                <id name="seq" column="seq" type="long">
                   <generator class="sequence">
                      <param name="sequence">TSTQ_ADD</param>
                   </generator>
                </id>
                <property name="description" column="DESCRIPTION"/>
        </class>
</hibernate-mapping>
Two tables:
Code:
create table PERSON
(
  SEQ  NUMBER not null,
  NAME VARCHAR2(200) not null
)
create table ADDRESS
(
  SEQ         NUMBER not null,
  DESCRIPTION VARCHAR2(200) not null,
  PER_SEQ     NUMBER not null
)
The PersonDAO.java:
Code:
package test.dao;
import java.sql.Connection;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.FetchMode;
import org.hibernate.Hibernate;
import org.hibernate.JDBCException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import test.domain.Person;
import br.gov.rs.mp.util.HibernateUtil;
import br.gov.rs.mp.util.sql.SQLExceptionWrapper;
public class PersonDAO {
   
   private final static Logger LOG = Logger.getLogger(PersonDAO.class.getName());
   private static final SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
   private Connection connection;
   
   public PersonDAO(Connection connection){
      this.connection = connection;
   }
   
   public Connection getConnection() {
      return connection;
   }
   
   public List getList() {
      List persons = null;
      
      try {
         Session session = sessionFactory.openSession(getConnection());
         Query q = session.createQuery("from Person");
         persons = q.list();
         session.close();
      } catch (Exception e) {
         LOG.error("Erro inesperado.", e);
         throw new RuntimeException("Erro inesperado.", e);
      }
      
      return persons;
   }
   
   public Person get(Person per){
      
      Person person = null;
      
      try {
         Session session = sessionFactory.openSession(getConnection());
         
         person = (Person)session.createCriteria(Person.class)
            .setFetchMode("addresses", FetchMode.JOIN)
            .add( Restrictions.idEq(new Long(per.getSeq())) )
                .uniqueResult();
         Hibernate.initialize(person.getAddresses());
         session.close();
      } catch (Exception e) {
         LOG.error("Erro inesperado.", e);
         throw new RuntimeException("Erro inesperado.", e);
      }
      
      return person;
   }
   
   public boolean delete(Person person) {
      
      Session session = sessionFactory.openSession(getConnection());
      Transaction trans = session.beginTransaction();
      
      try {
         person = this.get(person);
         session.delete(person);
         trans.commit();
         
      } catch (JDBCException e) {
         try {
            trans.rollback();
         } catch (Exception ex) {
            LOG.error("Erro ao desfazer transação.", ex);
         }
         
         SQLExceptionWrapper wrapper = new SQLExceptionWrapper(e.getSQLException(), getConnection());
         LOG.log(wrapper.getLoggerPriority(), wrapper.getMessage(), e);
         throw new RuntimeException(wrapper.getMessage(), e);
         
      } catch (Exception e) {
         
         try {
            trans.rollback();
         } catch (Exception ex) {
            LOG.error("Erro ao desfazer transação.", ex);
         }
         
         LOG.error("Erro inesperado.", e);
         throw new RuntimeException("Erro inesperado.");
         
      } finally {
         if (session != null) {
            try {
               session.close();
            } catch (Exception ignored){}
         }
      }
      
      return true;
   }
   
   public boolean insert(Person person) {
      
      Session session = sessionFactory.openSession(getConnection());
      Transaction trans = session.beginTransaction();
      
      try {
         session.save(person);
         trans.commit();
         
      } catch (JDBCException e) {
         try {
            trans.rollback();
         } catch (Exception ex) {
            LOG.error("Erro ao desfazer transação.", ex);
         }
         
         SQLExceptionWrapper wrapper = new SQLExceptionWrapper(e.getSQLException(), getConnection());
         LOG.log(wrapper.getLoggerPriority(), wrapper.getMessage(), e);
         throw new RuntimeException(wrapper.getMessage(), e);
         
      } catch (Exception e) {
         
         try {
            trans.rollback();
         } catch (Exception ex) {
            LOG.error("Erro ao desfazer transação.", ex);
         }
         
         LOG.error("Erro inesperado.", e);
         throw new RuntimeException("Erro inesperado.");
         
      } finally {
         if (session != null) {
            try {
               session.close();
            } catch (Exception ignored){}
         }
      }
      return true;
   }
   
   public boolean update(Person person) {
      Session session = sessionFactory.openSession(getConnection());
      Transaction trans = session.beginTransaction();
      
      try {
         session.update(person);
         trans.commit();
         
      } catch (JDBCException e) {
         try {
            trans.rollback();
         } catch (Exception ex) {
            LOG.error("Erro ao desfazer transação.", ex);
         }
         
         SQLExceptionWrapper wrapper = new SQLExceptionWrapper(e.getSQLException(), getConnection());
         LOG.log(wrapper.getLoggerPriority(), wrapper.getMessage(), e);
         throw new RuntimeException(wrapper.getMessage(), e);
         
      } catch (Exception e) {
         
         try {
            trans.rollback();
         } catch (Exception ex) {
            LOG.error("Erro ao desfazer transação.", ex);
         }
         
         LOG.error("Erro inesperado.", e);
         throw new RuntimeException("Erro inesperado.");
         
      } finally {
         if (session != null) {
            try {
               session.close();
            } catch (Exception ignored){}
         }
      }
      
      return true;
   }
}
And now the main method:
Code:
   public static void main(String[] args) {
      try {
         Class.forName("oracle.jdbc.driver.OracleDriver");
         Connection conn = DriverManager.getConnection(...);
         
         PersonDAO dao = new PersonDAO(conn);
         
         Person person = new Person();
         person.setName("Me");
         dao.insert(person);
         
         person = dao.get(person);
         
         Address addr = new Address();
         person.getAddresses().add(addr);
         System.out.println("address.seq=" + addr.getSeq());
         
         try {
            // Here, some error occurs, at database level:
            // address.description can't be null
            dao.update(person);
         } catch (RuntimeException e) {
            e.printStackTrace();
         }
         
         System.out.println("address.seq=" + addr.getSeq());
         // now sets the description
         addr.setDescription("New Address");
         
         try {
            // Now, no error occurs at database level, but errors occurs 
            // because hibernate tries to update an address that 
            // still does not exists in the database
            dao.update(person);
         } catch (RuntimeException e) {
            e.printStackTrace();
         }
         
      } catch (Exception e) {
         e.printStackTrace();
         System.exit(0);
      }
   }
The stacktrace shows an error caused by the first update (ORA-01400: cannot insert NULL into ("ADDRESS"."DESCRIPTION"),
followed by another error caused by the second update (Could not synchronize database state with session,
org.hibernate.StaleStateException: Unexpected row count: 0 expected: 1)
The two outs show different values for address.seq.
Please understand, my application 
MUST handle database level errors, this is a big requirement for compatibility with other existent systems.
Thanks in advance