nhibernate: why does nhibernate update the foreign key of my child entity?
Ok, i have two entities named WorkPostSheet and WorkPost where the WorkPostSheet contains a collection of WorkPost-items:
public class WorkPostSheet
{
...
public virtual IEnumerable<WorkPost> WorkPosts
{
get;
private set;
}
}
In my integration test, i notice that nhibernate creates an update statement which I cannot understand. The test:
[Test]
public void Commit_CreateNewWorkPostSheetWithWorkPosts_WorkPostsPersisted()
{
using (IUnitOfWork unitOfWork = IsolatingFactory.CreateReadOnlyUnitOfWork())
{
// arrange
WorkPostSheetRepository repository = new WorkPostSheetRepository(IsolatingFactory);
WorkItemRepository workItemRepository = new WorkItemRepository(IsolatingFactory);
DateTime from = new DateTime(2000, 1, 1);
DateTime to = new DateTime(2000, 2, 1);开发者_JS百科
WorkPostSheet sheetWithWorkPosts = WorkPostSheet.Create(TestData.CreateAndCommitUser("min", "Marius", "Ingjer", IsolatingFactory), new TimePeriod(from, to));
WorkItem workItemToPostWorkOn = WorkItem.Create(0, "A");
workItemRepository.Commit(workItemToPostWorkOn);
WorkPost workPost = sheetWithWorkPosts.Add(workItemToPostWorkOn, from);
// act
repository.Commit(sheetWithWorkPosts);
unitOfWork.Session.Flush();
unitOfWork.Session.Clear();
WorkPostSheet sheetWithWorkPostsFromDb = repository.Get(sheetWithWorkPosts.Id, false);
// assert
CollectionAssert.Contains(sheetWithWorkPostsFromDb.WorkPosts, workPost);
}
}
The output:
NHibernate: INSERT INTO "User" (UserName, FirstName, LastName) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 'min', @p1 = 'Marius', @p2 = 'Ingjer'
This makes sence since I am creating a user (TestData.CreateAndCommitUser)
NHibernate: INSERT INTO "WorkItem" (LastChanged, Description, Id) VALUES (@p0, @p1, @p2);@p0 = 06.01.2010 21:50:25, @p1 = 'A', @p2 = 0
This makes sence since I am creating a workitem
NHibernate: INSERT INTO "WorkPostSheet" (PeriodFrom, PeriodTo, userId) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 01.01.2000 00:00:00, @p1 = 01.02.2000 00:00:00, @p2 = 1
This makes sence as I am creating a workpost sheet
NHibernate: INSERT INTO "WorkPost" (WorkDone, workItemId, sheetId) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 0, @p1 = 0, @p2 = 1
This is commited in the WorkPostRepository (workpost sheet is root entity)
NHibernate: UPDATE "WorkPost" SET sheetId = @p0 WHERE Id = @p1;@p0 = 1, @p1 = 1
Now this one I not understand. The foreign is updated with the same value assigned when the entity was first commited. Can you help me understand this?
NHibernate: SELECT workpostsh0_.Id as Id3_1_, workpostsh0_.PeriodFrom as PeriodFrom3_1_, workpostsh0_.PeriodTo as PeriodTo3_1_, workpostsh0_.userId as userId3_1_, user1_.Id as Id0_0_, user1_.UserName as UserName0_0_, user1_.FirstName as FirstName0_0_, user1_.LastName as LastName0_0_ FROM "WorkPostSheet" workpostsh0_ inner join "User" user1_ on workpostsh0_.userId=user1_.Id WHERE workpostsh0_.Id=@p0;@p0 = 1
Load from repository
NHibernate: SELECT workposts0_.sheetId as sheetId2_, workposts0_.Id as Id2_, workposts0_.Id as Id2_1_, workposts0_.WorkDone as WorkDone2_1_, workposts0_.workItemId as workItemId2_1_, workposts0_.sheetId as sheetId2_1_, workitem1_.Id as Id1_0_, workitem1_.LastChanged as LastChan2_1_0_, workitem1_.Description as Descript3_1_0_ FROM "WorkPost" workposts0_ inner join "WorkItem" workitem1_ on workposts0_.workItemId=workitem1_.Id WHERE workposts0_.sheetId=@p0;@p0 = 1
Lazy load
Here are the mapping files:
sealed class WorkPostClassMap : ClassMap<WorkPost>
{
public WorkPostClassMap()
{
Not.LazyLoad();
Id(post => post.Id).GeneratedBy.Identity().UnsavedValue(0);
Map(post => post.WorkDone);
References(post => post.Item).Column("workItemId").Not.Nullable();
References(Reveal.Property<WorkPost, WorkPostSheet>("Owner"), "sheetId").Not.Nullable();
}
}
sealed class WorkPostSheetClassMap : ClassMap<WorkPostSheet>
{
public WorkPostSheetClassMap()
{
Id(sheet => sheet.Id).GeneratedBy.Identity().UnsavedValue(0);
Component(sheet => sheet.Period, period =>
{
period.Map(p => p.From, "PeriodFrom");
period.Map(p => p.To, "PeriodTo");
});
References(sheet => sheet.Owner, "userId").Not.Nullable();
HasMany(sheet => sheet.WorkPosts).KeyColumn("sheetId").AsBag();
}
}
Did you set the "inverse" attribute to "true" for the collection side of the association?
See: http://ayende.com/Blog/archive/2009/01/18/nh-prof-new-feature-superfluous-ltmany-to-onegt-update.aspx
精彩评论