Hello all,
I have the following (simplified) mappings:
public class RosterMap : ClassMap<Roster>
{
public RosterMap()
{
References(tr => tr.Team)
.Not.Nullable();
HasMany(r => r.Players)
.Inverse()
.Cascade.AllDeleteOrphan();
References(roster => roster.Match)
.Nullable();
}
}
public class TeamMap : ClassMap<Team>
{
public TeamMap()
{
HasMany(t => t.Rosters)
.Inverse()
.Cascade.AllDeleteOrphan();
HasMany(t => t.MatchesAtHome);
HasMany(t => t.MatchesOnRoad);
}
}
public class MatchMap : ClassMap<Match>
{
public MatchMap()
{
References(m => m.HomeTeam)
.Cascade.All()
.Not.Nullable();
References(m => m.RoadTeam)
.Cascade.All()
.Not.Nullable();
References(m => m.HomeRoster)
.Cascade.All();
References(m => m.RoadRoster)
.Cascade.All();
}
}
I wrote a unit test to check I can successfully save a match in the database:
using (var session = Kernel.Get<ISession>())
{
var p1 = new Player("P1", "P1", 5);
session.Save(p1);
var p2 = new Player("P2", "P2", 5);
session.Save(p2);
Team homeTeam = new Team("Home", Sex.Male);
session.Save(homeTeam);
homeTeam.DefaultRoster.AddPlayer(p1);
foreach (var pit in homeTeam.DefaultRoster.Players)
session.Save(pit);
session.Save(homeTeam.DefaultRoster);
Team roadTeam = new Team("Road", Sex.Male);
session.Save(roadTeam);
roadTeam.DefaultRoster.AddPlayer(p2);
foreach (var pit in roadTeam.DefaultRoster.Players)
session.Save(pit);
session.Save(roadTeam.DefaultRoster);
session.Flush();
var match = new Match
{
Name = "Fuu",
Date = DateTime.Now,
Location = "Here",
HomeTeam = homeTeam,
RoadTeam = roadTeam
};
match.HomeRoster.UpdatePlayers(homeTeam.DefaultRoster.Players.Select(pit => pit.Player));
match.RoadRoster.UpdatePlayers(roadTeam.DefaultRoster.Players.Select(pit => pit.Player));
session.Save(match);
session.Flush();
}
This works, and generates the following SQL:
NHibernate: INSERT INTO Players (Sex, FirstName, LastName, DefaultNumber, Visible, DefaultPosition_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);@p0 = 0 [Type: Int32 (0)], @p1 = 'P1' [Type: String (0)], @p2 = 'P1' [Type: String (0)], @p3 = 5 [Type: Int32 (0)], @p4 = True [Type: Boolean (0)], @p5 = NULL [Type: Int32 (0)], @p6 = 1 [Type: Int32 (0)]
NHibernate: INSERT INTO Players (Sex, FirstName, LastName, DefaultNumber, Visible, DefaultPosition_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6);@p0 = 0 [Type: Int32 (0)], @p1 = 'P2' [Type: String (0)], @p2 = 'P2' [Type: String (0)], @p3 = 5 [Type: Int32 (0)], @p4 = True [Type: Boolean (0)], @p5 = NULL [Type: Int32 (0)], @p6 = 2 [Type: Int32 (0)]
NHibernate: INSERT INTO Teams (Sex, Name, Visible, Location, Id) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 0 [Type: Int32 (0)], @p1 = 'Home' [Type: String (0)], @p2 = True [Type: Boolean (0)], @p3 = '' [Type: String (0)], @p4 = 1 [Type: Int32 (0)]
NHibernate: INSERT INTO "Roster" (Team_id, Match_id, Id) VALUES (@p0, @p1, @p2);@p0 = 1 [Type: Int32 (0)], @p1 = NULL [Type: Int32 (0)], @p2 = 1 [Type: Int32 (0)]
NHibernate: INSERT INTO "PlayerInTeam" (PlayerNumber, Player_id, Position_id, Roster_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 5 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)], @p2 = NULL [Type: Int32 (0)], @p3 = 1 [Type: Int32 (0)], @p4 = 1 [Type: Int32 (0)]
NHibernate: INSERT INTO Teams (Sex, Name, Visible, Location, Id) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 0 [Type: Int32 (0)], @p1 = 'Road' [Type: String (0)], @p2 = True [Type: Boolean (0)], @p3 = '' [Type: String (0)], @p4 = 2 [Type: Int32 (0)]
NHibernate: INSERT INTO "Roster" (Team_id, Match_id, Id) VALUES (@p0, @p1, @p2);@p0 = 2 [Type: Int32 (0)], @p1 = NULL [Type: Int32 (0)], @p2 = 2 [Type: Int32 (0)]
NHibernate: INSERT INTO "PlayerInTeam" (PlayerNumber, Player_id, Position_id, Roster_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 5 [Type: Int32 (0)], @p1 = 2 [Type: Int32 (0)], @p2 = NULL [Type: Int32 (0)], @p3 = 2 [Type: Int32 (0)], @p4 = 2 [Type: Int32 (0)]
NHibernate: INSERT INTO "Roster" (Team_id, Match_id, Id) VALUES (@p0, @p1, @p2);@p0 = 1 [Type: Int32 (0)], @p1 = NULL [Type: Int32 (0)], @p2 = 3 [Type: Int32 (0)]
NHibernate: INSERT INTO "PlayerInTeam" (PlayerNumber, Player_id, Position_id, Roster_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 5 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)], @p2 = NULL [Type: Int32 (0)], @p3 = 3 [Type: Int32 (0)], @p4 = 3 [Type: Int32 (0)]
NHibernate: INSERT INTO "Roster" (Team_id, Match_id, Id) VALUES (@p0, @p1, @p2);@p0 = 2 [Type: Int32 (0)], @p1 = NULL [Type: Int32 (0)], @p2 = 4 [Type: Int32 (0)]
NHibernate: INSERT INTO "PlayerInTeam" (PlayerNumber, Player_id, Position_id, Roster_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 5 [Type: Int32 (0)], @p1 = 2 [Type: Int32 (0)], @p2 = NULL [Type: Int32 (0)], @p3 = 4 [Type: Int32 (0)], @p4 = 4 [Type: Int32 (0)]
NHibernate: INSERT INTO Matches (Name, Date, Location, Championship_id, HomeTeam_id, RoadTeam_id, HomeRoster_id, RoadRoster_id, Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8);@p0 = 'Fuu' [Type: String (0)], @p1 = 8/10/2010 17:24:18 [Type: DateTime (0)], @p2 = 'Here' [Type: String (0)], @p3 = NULL [Type: Int32 (0)], @p4 = 1 [Type: Int32 (0)], @p5 = 2 [Type: Int32 (0)], @p6 = 3 [Type: Int32 (0)], @p7 = 4 [Type: Int32 (0)], @p8 = 1 [Type: Int32 (0)]
NHibernate: UPDATE "Roster" SET Team_id = @p0, Match_id = @p1 WHERE Id = @p2;@p0 = 1 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)], @p2 = 3 [Type: Int32 (0)]
NHibernate: UPDATE "Roster" SET Team_id = @p0, Match_id = @p1 WHERE Id = @p2;@p0 = 2 [Type: Int32 (0)], @p1 = 1 [Type: Int32 (0)], @p2 = 4 [Type: Int32 (0)]
Now, I'd like 2 things:
- Set in the MatchMap, that HomeRoster and RoadRoster can't be null
- Avoid that, at the end of the SQL, the insertions of the match rosters, and after the match is inserted, an update of the rosters, and replace this by 3 single INSERT.
For #2, I don't know how to do, since there aren't any HasMany mappings between my entities, and then I can't set Inverse().
For #1: I've added .Not.Nullable() to the mappings for HomeRoster and TeamRoster in MatchMap, but then, I've got a ConstraintViolationException on the first call to Flush(), and once again, I really don't know why.
Any help?
Thanks in advance
Mike