2
votes

I've following mapping for two tables having a Many-to-Many relationship between them. How do I delete an entry from the mapping table, which is 'TB_EMAIL_GRUPO_ARQUIVO' in my case? I just need to delete the data from this "joining" table and I don´t need to delete it from the "parent tables".

GrupoModulo

public GrupoModuloMap()
{
    Schema(Const.SCHEMA);
    Table(Const.TB_EMAIL_GRUPO_MODULO);

    CompositeId()
        .KeyReference(x => x.Grupo, Const.ID_GRUPO)
        .KeyReference(x => x.Modulo, Const.ID_MODULO);

    Map(x => x.GrupoId).Column(Const.ID_GRUPO).ReadOnly();
    Map(x => x.ModuloId).Column(Const.ID_MODULO).ReadOnly();

    HasManyToMany(x => x.Arquivos)
        .Table(Const.TB_EMAIL_GRUPO_ARQUIVO)
        .ParentKeyColumns.Add(Const.ID_GRUPO, Const.ID_MODULO)
        .ChildKeyColumn(Const.ID_ARQUIVO)
        .Cascade.SaveUpdate()
        .Not.LazyLoad();
}

ArquivoRetorno

public ArquivoRetornoMap()
{
    Schema(Const.SCHEMA);
    Table(Const.TB_EMAIL_ARQUIVO_RETORNO);

    Id(x => x.Id)
        .Column(Const.ID_ARQUIVO)
        .GeneratedBy.Sequence("SEQ_TB_EMAIL_ARQUIVO_RETORNO")
        .Length(7).CustomSqlType("number(7)")
        .Not.Nullable();

    Map(x => x.Nome)
        .Column("NM_ARQUIVO_RETORNO")
        .Length(50)
        .Not.Nullable();

    References(x => x.Modulo)
        .Column(Const.ID_MODULO)
        .Not.Nullable();

    HasManyToMany(x => x.GrupoModulos)
        .Table(Const.TB_EMAIL_GRUPO_ARQUIVO)
        .ChildKeyColumns.Add(Const.ID_GRUPO, Const.ID_MODULO)
        .ParentKeyColumn(Const.ID_ARQUIVO)
        .Cascade.SaveUpdate()
        .Not.LazyLoad();
}

Whenever I try to delete I'm getting the following error:

deleted object would be re-saved by cascade (remove deleted object from associations)[Domain.Entity.GrupoModulo#Domain.Entity.GrupoModulo]

Someone has any idea?

1

1 Answers

4
votes

The answer is (I am really sure) here: NHibernate Deleted object would be re-saved by cascade

Let me re-phrase that for your case, what could happen:

  1. we remove an GrupoArquivo from ArquivoRetorno.GrupoModulos collection.
  2. During that transaction, unit of work, we also tuch and therefore load the GrupoModulo
  3. GrupoModulo gets initiated - and NOW - collection of Arquivos is loaded. So the reference to removed GrupoArquivo is kept there
  4. NHibernate MUST inform: Deleted object would be re-saved by cascade

Solution(s):

  • be sure that the GrupoModulo is never loaded (stays as proxy)
  • or (the way I use) Remove() the GrupoArquivo also from GrupoModulo.Arquivos
  • or do NOT use CASCADE mapping on GrupoArquivo side:

(do not use the cascade)

HasManyToMany(x => x.Arquivos)
    .Table(Const.TB_EMAIL_GRUPO_ARQUIVO)
    .ParentKeyColumns.Add(Const.ID_GRUPO, Const.ID_MODULO)
    .ChildKeyColumn(Const.ID_ARQUIVO)
    //.Cascade.SaveUpdate()
    // here
    .Cascade.None()
    .Not.LazyLoad();