Directamente desde documentation. Esto explica su problema exactamente creo:
Sin embargo, este código
Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;
p.Children.Remove(c);
c.Parent = null;
session.Flush();
no eliminará c de la base de datos; solo eliminará el enlace a p (y provocará una violación de restricción NOT NULL, en este caso). Necesita eliminar explícitamente() al Niño.
Parent p = (Parent) session.Load(typeof(Parent), pid);
// Get one child out of the set
IEnumerator childEnumerator = p.Children.GetEnumerator();
childEnumerator.MoveNext();
Child c = (Child) childEnumerator.Current;
p.Children.Remove(c);
session.Delete(c);
session.Flush();
Ahora, en nuestro caso, un Niño realmente no puede existir sin su padre. Entonces, si eliminamos un elemento secundario de la colección, realmente queremos que se elimine. Para esto, debemos usar cascade = "all-delete-huérfano".
<set name="Children" inverse="true" cascade="all-delete-orphan">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
Editar:
Con respecto a la materia inversa, creo que esto sólo determina cómo se genera el SQL, vea este doc para obtener más información.
Una cosa a tener en cuenta es, ¿tienes
not-null="true"
en la relación uno-a-muchos en su configuración de hibernación?
Probablemente deberías mostrar las partes relevantes de tus mapeos. Uso all-delete-huérfano todo el tiempo con claves externas no nulas y nunca he tenido un problema. –