Hi all. I have a problem that nh is performing an UPDATE for 3 entities I've 
just created, and getting a batch update failed, actual: 0, expected 3. I can 
see why, because these entities don't exist, so there is nothing to update, but 
I'm curious as to the mechanism that the uow is coming to decide that they're 
existing. In debug mode my code will output all sqls ever run by nH to the 
console, and there is definitely never an INSERT for these entities 

The problem only appeared after upgrading the nuget package from 2.x to 5.2

In terms of the data structure in the db, a project has many projectgroups and 
a project has many projectparticipants. Many projectparticipants have many 
projectgroups and this m:m relationship is decomposed by a 
projectgroupparticipants table

 I create 2 ProjectParticipants and add them to the Project.Participants 
collection. Then I populate the Project.Groups collection with 3 new groups. 
Finally I cross reference them by adding the participants to the relevant 
groupX.Participants, and adding the group to participantX,Groups. (Group A has 
participant 1, Group B has participant 2, Group C has participants 1 and 2)
Upon saving the changes I encounter a "StaleStateException - Batch update 
returned unexpected row count from update; actual row count: 0, expected: 3" in 
relation to creating the 3 groups. I would expect nHibernate to INSERT the new 
groups but it's running an UPDATE query and balking that they don't exist. It 
doesn't get as far as assigning the the participants to the groups 

Here are the mappings:

    //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);


The tables are (hopefully doesn't get messed up):

    [ProjectParticipants] 1-->M [ProjectGroupParticipants] M<--1 [ProjectGroups]
                  M                                                   M
                  \---------------->1 [Project] 1<--------------------/


Here are the SQLs being run by 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 ]

So why did nHibernate come to think that its local entity had already ben saved 
and was hence available to UPDATE? The SQL generated should be an insert, but 
I'm not sure how it manages sync between local cache and DB to know if entities 
already exist or not

Slightly puzzled, that this used to work in NH 2.x, but since an upgrade to 
latest (5.x) this exception has started appearing.

If any of the code/ascii art diagram above is messed up, there is a markdown 
formatted version of this question on SO at 
https://stackoverflow.com/questions/56365708/nhibernate-is-trying-to-sql-update-an-entity-i-just-created-rather-than-insert

Many thanks for any pointers

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/nhusers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/nhusers/c7f31078-ac98-4fb2-852f-fff1cf4626b9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to