user53731
user53731

Reputation: 11

Cascade.SaveOrUpdate (SQLite) fluent-nhibernate

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();
    }
}

Upvotes: 1

Views: 2811

Answers (2)

Kenneth
Kenneth

Reputation: 1

ALWAYS do your Save in a transaction.

Cheers

Upvotes: -2

Rob Scott
Rob Scott

Reputation: 449

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'

Upvotes: 5

Related Questions