How to save a cascade collection in nhibernate without putting circular reference?

Asked

Viewed 960 times

9

Always when I try to save an object with a data collection mapped as HasMany I have to put a circular reference so that Nhibernate can save this object in cascade.

For example I have the following parent class mapping.

public class ClasseMap : ClassMap<Classe>
{
    public ClasseMap()
    {
      Table("tClasse");

      HasMany<Metodo>(t => t.Metodos)
     .KeyColumn("IdClasse")
     .Inverse()
     .Cascade
     .SaveUpdate();
    }
}

And in the daughter class

public class MetodoMap : ClassMap<Metodo>
{
    public MetodoMap()
    {
      Table("tMetodo");

      References(t => t.Classe)
            .Column("IdClasse")
            .ForeignKey("FK_Metodo_IdClasse");
    }
}

When I will save the data of my object Classe I’ll tell you what:

public class RepositorioClasse
{
    protected readonly ISession SessaoAtual;

    public RepositorioClasse(ISession sessaoAtual)
    {
        SessaoAtual = sessaoAtual;
    }

    public SalvaEntidades() {
        var classe = new Classe();
        var metodo = new Metodo(){
                           Nome= "ToString",
                           TipoRetorno="String",
                           Classe= classe
                          };    

        classe.Nome = "String";
        classe.Metodos.Add(metodo);

        SessaoAtual.SaveUpdate(classe);
   }
}

If I only put up a collection of Metodos in Classe and remove the reference to Classe in Metodo Nhibernate does not save and returns an exception saying that I must have a reference of Classe in Metodo.

  • 1

    Hello Mark. Could you complement your question by placing the original message of the exception which occurs?

2 answers

2


Noting his comment:

[...] Having all this information Nhibernate could simply give an Insert in the table tClasse and then give an Insert in the table tMetodo by entering in the Idclass field the id of the class I have just completed salvage

That will not happen in this case because in the clause HasMany you defined the relationship as .Inverse(). In practice, what you’re saying is that the daughter entity (in this case, Metodo) is that will be responsible for keeping track of the relationship between the two (i.e., the opposite of what you intend).

If you have sharp English, I suggest you read this little piece of documentation of Nhibernate.

In short: Try to remove the Inverse(). IS possible work.

  • 1

    I did the test using Sqlite and left the mapping without Inverse(), at first Nhibernate saved the two entities but did not save the tClasse key in the table of tMetodo. However I added in the mapping of my collection of Methods a Not.Keynullable() and it worked great.

  • Show! Good to know :)

0

Thinking only of databases (without NH), how would you make a SELECT in the Methods table to bring the methods of a particular Class without having the Class.Id in that table (FK)? Could you see the problem?

It makes no sense to have a collection of Methods within Class without having the Class Id within Method. It is through this Id that the NH knows what Methods he has to look for to fill the collection. If we didn’t have this Class ID, the NH would have to search for ALL records in the Methods table, which means that there is no relationship between the two entities.

  • Yes, thinking about the bank doesn’t make sense I don’t have a tClasse table FK in tMetodo table, so in the mapping I say pro Nhibernate keyColunm("Idclasse") or be my FK in tMetodo table is Idclasse. So through the mapping he knows that FK is Idclasse and knows that the table where to save the child record is tMetodo because the type of my collection is Metodo. Having all this information Nhibernate could simply give an Insert in the tClasse table and then give an Insert in the tMetodo table by inserting in the Idclass field the id of the class I just saved.

  • @Iscoder "It makes no sense to have a collection of Methods within Class without having the Class Id within Method.", but, but... but he has FK there yes! (Column IdClasse, Constraint FK_Metodo_IdClasse)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.