Участник проекта может быть членом многих групп, а в группе может быть много участников проекта
Я обнаружил, что когда я создаю 2 участника ProjectParticipant (это работает), а затем заполняю коллекцию Project.Groups
значением 3 новые группы и добавление участников в соответствующие группы (в группе A есть участник 1, в группе B есть участник 2, в группе C есть участники 1 и 2), я обнаружил «StaleStateException - пакетное обновление вернуло неожиданное количество строк изобновление; фактическое количество строк: 0, ожидаемое: 3 ".Я ожидаю, что nHibernate вставит новые группы, но он выполняет запрос UPDATE и предупреждает, что они не существуют.Это не так далеко, как назначение участников в группы
Вот сопоставления:
//ProjectMap: A Project..
Id(x => x.Id).GeneratedBy.GuidComb().UnsavedValue(Guid.Empty);
HasMany(x => x.Participants)
.Table("ProjectParticipants")
.KeyColumn("ProjectId")
.ApplyFilter(DeletedDateFilter.FilterName)
.Cascade.AllDeleteOrphan()
.Inverse();
HasMany(x => x.Groups)
.Table("ProjectGroups")
.KeyColumn("ProjectId")
.Cascade.AllDeleteOrphan()
.Inverse();
//ProjectParticipantMap: A ProjectParticipant…
Id(x => x.Id).GeneratedBy.GuidComb().UnsavedValue(Guid.Empty);
References(x => x.Project)
.Column("ProjectId")
.LazyLoad(Laziness.Proxy);
HasManyToMany(x => x.Groups)
.Table("ProjectGroupParticipants")
.ParentKeyColumn("ProjectParticipantId")
.ChildKeyColumn("ProjectGroupId");
//GroupMap: A Group...
Id(e => e.Id).GeneratedBy.Assigned().UnsavedValue(Guid.Empty);
References(e => e.Project)
.Column("ProjectId")
.LazyLoad(Laziness.Proxy);
HasManyToMany(x => x.Participants)
.Table("ProjectGroupParticipants")
.ParentKeyColumn("ProjectGroupId")
.ChildKeyColumn("ProjectParticipantId")
.ApplyChildFilter(DeletedDateFilter.FilterName);
Таблицы:
[ProjectParticipants] 1-->M [ProjectGroupParticipants] M<--1 [ProjectGroups]
M M
\---------------->1 [Project] 1<--------------------/
ВотSQL, выполняемые nHibernate:
--presume this is adding the first participant - I find him in the db
INSERT INTO ProjectParticipants (CreatedDate, ModifiedDate, DeletedDate, FirstName, LastName, Timezone, Email, Pseudonym, Role, ProjectId, UserId, MobileNumber, Id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
--presume this is adding the second participant - I find her in the DB
INSERT INTO ProjectParticipants (CreatedDate, ModifiedDate, DeletedDate, FirstName, LastName, Timezone, Email, Pseudonym, Role, ProjectId, UserId, MobileNumber, Id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
--not sure what this is doing
UPDATE Projects SET CreatedDate = ?, ModifiedDate = ?, LogoUrl = ?, LogoFilename = ?, Client = ?, Name = ?, Description = ?, LastAccessedDate = ? WHERE Id = ?
--not sure what this operation is for, but at this point in time NO GROUP EXISTs for this project ID
SELECT … FROM ProjectGroups groups0_ WHERE groups0_.ProjectId=?
--not sure what this is for either?
UPDATE Projects SET CreatedDate = ?, ModifiedDate = ?, LogoUrl = ?, LogoFilename = ?, Client = ?, Name = ?, Description = ?, LastAccessedDate = ? WHERE Id = ?
-- I've no idea why this is an UPDATE instead of an INSERT, but it will certainly update 0 rows instead of X, because no groups exist
UPDATE ProjectGroups SET CreatedDate = ?, ModifiedDate = ?, DeletedDate = ?, Name = ?, ProjectId = ? WHERE Id = ?
Exception thrown: 'NHibernate.StaleStateException' in NHibernate.dll
Batch update returned unexpected row count from update; actual row count: 0; expected: 3
[ UPDATE ProjectGroups SET CreatedDate = @p0, ModifiedDate = @p1, DeletedDate = @p2, Name = @p3, ProjectId = @p4 WHERE Id = @p5 ]
Так почему же nHibernate решил, что его локальная сущность уже сохранена и, следовательно, доступна для UPDATE?Сгенерированный SQL должен быть вставкой, но я не уверен, как он управляет синхронизацией между локальным кешем и БД, чтобы узнать, существуют ли уже сущности или нет
Немного озадачен, что это работало в NH 2.x, но после обновления до последней версии (5.x) это исключение стало появляться.