views:

1371

answers:

3

Hi,

I have a many-to-many relationship between two classes: Tournament and Players

I set Cascade.SaveUpdate in the mappings, but when saving a Tournament instance, the Players will not be saved to the Players table. Nhibernate only writes parent and child key columns in the linking table. The DB is SQLite.

These are the mappings

 public TournamentMap()
    {
        WithTable("Tournaments");
        Id(x => x.Name);
        Map(x => x.Start).Access.AsLowerCaseField();
        Map(x => x.End).Access.AsLowerCaseField();

        HasManyToMany<Player>(x => x.Players)
            .WithTableName("TournamentsPlayers")
            .WithParentKeyColumn("tournamentName")
            .WithChildKeyColumn("playerName").AsSet()
            .Access.AsLowerCaseField()
            .Cascade.SaveUpdate().LazyLoad();

        References(x => x.Type).Access.AsLowerCaseField()
            .TheColumnNameIs("typeName")
            .Cascade.SaveUpdate();
    }

  public class PlayerMap : ClassMap<Player>
{
    public PlayerMap()
    {
        WithTable("Players");
        Id(x => x.Name);

        HasManyToMany<Player>(x => x.Tournaments)
            .Access.AsLowerCaseField()
            .WithTableName("TournamentsPlayers")
            .WithParentKeyColumn("playerName")
            .WithChildKeyColumn("tournamentName").AsSet()
            .Cascade.SaveUpdate().IsInverse().LazyLoad();
    }
}
A: 

Please show the code you use to save the Players and Tournament to the database

sirrocco
+3  A: 

Maybe a little (or a lot) late, but nonetheless,

I simplified your example to look like this:

public class Tournament
{
    public virtual Guid Id { get; private set; }

    private readonly ISet<Player> players;

    public Tournament()
    {
        players = new HashedSet<Player>();
    }

    public virtual ISet<Player> Players
    {
        get { return players; }
    }

    public virtual void AddPlayer(Player player)
    {
        players.Add(player);
    }
}

public class Player 
{
    public virtual Guid Id { get; private set; }

    private readonly ISet<Tournament> tournaments;

    public Player()
    {
        tournaments = new HashedSet<Tournament>();
    }

    public virtual ISet<Tournament> Tournaments
    {
        get { return tournaments; }
    }

    public virtual void AddTournament(Tournament tournament)
    {
        tournaments.Add(tournament);
    }
}

public class TournamentMap : ClassMap<Tournament>
{
    public TournamentMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();

        HasManyToMany<Player>(x => x.Players)
            .AsSet().Access.AsLowerCaseField()
            .Cascade.SaveUpdate();
    }
}
public class PlayerMap : ClassMap<Player>
{
    public PlayerMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();

        HasManyToMany<Tournament>(x => x.Tournaments)
            .Access.AsLowerCaseField()
            .AsSet()
            .Cascade.SaveUpdate().Inverse();
    }
}

The first test looks like:

   [Test]
    public void CanSavePlayerAttachedToTournament()
    {
        Player player = new Player();
        Tournament tournament = new Tournament();
        player.AddTournament(tournament);
        tournament.AddPlayer(player);
        Session.Save(tournament);
        Session.Flush();
    }

and yields the following sql:

NHibernate: INSERT INTO "Tournament" (Id) VALUES (@p0); @p0 = '65559bba-8603-4874-8a8f-9bf4018596df' NHibernate: INSERT INTO "Player" (Id) VALUES (@p0); @p0 = '549e107c-1339-4fab-8960-9bf4018596e8' NHibernate: INSERT INTO PlayerToTournament (Tournament_id, Player_id) VALUES (@p0, @p1); @p0 = '65559bba-8603-4874-8a8f-9bf4018596df', @p1 = '549e107c-1339-4fab-8960-9bf4018596e8'

The second test looks like:

    [Test]
    public void CanSaveTounamentAttachedToPlayer()
    {
        Player player = new Player();
        Tournament tournament = new Tournament();
        player.AddTournament(tournament);
        tournament.AddPlayer(player);
        Session.Save(player);
        Session.Flush();
    }

and yields the following sql:

NHibernate: INSERT INTO "Player" (Id) VALUES (@p0); @p0 = '35c078c5-1102-4c63-91ca-9bf40185971c' NHibernate: INSERT INTO "Tournament" (Id) VALUES (@p0); @p0 = '367898cf-5835-4e1b-9d7d-9bf40185971c' NHibernate: INSERT INTO PlayerToTournament (Tournament_id, Player_id) VALUES (@p0, @p1); @p0 = '367898cf-5835-4e1b-9d7d-9bf40185971c', @p1 = '35c078c5-1102-4c63-91ca-9bf40185971c'

Rob Scott
A: 

ALWAYS do your Save in a transaction.

Cheers

Kenneth