Hello,

I have the following entity, Board, which represents Othello
positions:

        public class Board : Entity // Entity defines Id as Guid
        {
                private ISet<Board> successors = new HashSet<Board>();
                private ISet<Board> parents = new HashSet<Board>();
                public virtual long Empty { get; private set; }
                public virtual long Mover { get; private set; }
                public virtual IEnumerable<Board> Parents { get { return
parents; } }
                public virtual void AddParent(Board parent)
                {
                        parents.Add(parent);
                }
                public virtual IEnumerable<Board> Successors { get { return
successors; } }
                public virtual void AddSuccessor(Board successor)
                {
                        successors.Add(successor);
                }
                public virtual IEnumerable<Board> CalculateSuccessors()
                { ... }
        }

The intent is to store the positions along with their successors
(children) and predecessors (parents). The mapping I came up with
looks like this:

        public class BoardMap : ClassMap<Board>
        {
                public BoardMap()
                {
                        Id(x => x.Id);
                        NaturalId().Property(x => x.Empty).Property(x => 
x.Mover);
                        HasManyToMany(x => x.Successors)
                                .Access.ReadOnlyPropertyThroughLowerCaseField()
                                .ParentKeyColumn("ParentId")
                                .ChildKeyColumn("ChildId")
                                .Cascade.SaveUpdate()      // ?
                                .AsSet(SortType.Unsorted)
                                .Table("Successors");
                        HasManyToMany(x => x.Parents)
                                .Access.ReadOnlyPropertyThroughLowerCaseField()
                                .ParentKeyColumn("ParentId")
                                .ChildKeyColumn("ChildId")
                                .Cascade.SaveUpdate()     // ?
                                .AsSet(SortType.Unsorted)
                                .Table("Parents");
                }

Here's how I want to add a position. If the position already exists,
just skip it, otherwise set up the association between parent/
successor:

        // all of the following is running inside an ISession, wrapped with
transaction
        var parent = new Board(...);
        if (Find(parent) == null)
        {
                log.InfoFormat("Adding {0}: {1}", currentPosition++, parent);
                foreach (var s in parent.CalculateSuccessors())
                {
                        // get from store, if it exists
                        var successor = Find(s) ?? s;
                        successor.AddParent(parent);
                        parent.AddSuccessor(successor);
                }

                session.Save(parent);
        }
        else
        {
                log.InfoFormat("Existing {0}: {1}", currentPosition++, parent);
        }

Find simply looks like this:

        public Board Find(Board item)
        {
                // Transact will run inside the current transaction, or start 
new if
there is none
                return Transact(() => from b in session.Query<Board>()
                                                          where b.Empty == 
item.Empty && b.Mover == item.Mover
                                                          select 
b).SingleOrDefault();
        }

The problem I am seeing is that it seems cascading is doing too much.
I believe I've wrongly configured NHibernate to cascade to children's
children's children, etc. Even adding 91 positions takes too long.
Here's what I am seeing in the log output:

2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|processing
cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction
for: GridBook.Domain.Board
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Parents
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Parents
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done
processing cascade NHibernate.Engine.CascadingAction
+SaveUpdateCascadingAction for: GridBook.Domain.Board
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|processing
cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction
for: GridBook.Domain.Board
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors
2011-01-24 11:59:14.5344|INFO|NHibernate.Engine.Cascade|done cascade
NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for
collection: GridBook.Domain.Board.Successors

etc, several thousand lines for only 91 positions. What am I doing
wrong here? This could be considered batch-import and I will be
importing millions of positions.
Any advice would be greatly appreciated!

Thanks in advance!

Regards,

Daniel Lidström
Stockholm, Sweden

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to