I have the following 2 mappings:
internal RulesEngineHeaderMap()
{
Table("LIOEP023");
CompositeId()
.KeyProperty(x => x.CompanyCode, "CONO23")
.KeyProperty(x => x.RuleID, "RLID23");
Map(x => x.RuleGroup, "RGRP23")
.Length(30)
.Not.Nullable();
Map(x => x.RuleDescription, "RLDS23")
.Length(50)
.Not.Nullable();
Map(x => x.Expression, "EXPR23")
.Length(2500)
.Not.Nullable();
HasMany(x => x.RuleVariables)
.KeyColumns.Add("CONO24", "RLID24");
}
and
internal RulesEngineVariableDetailMap()
{
Table("LIOEP024");
CompositeId()
.KeyProperty(x => x.CompanyCode, "CONO24")
.KeyProperty(x => x.RuleID, "RLID24")
.KeyProperty(x => x.Name, "RVAR24");
Map(x => x.Type, "VTYP24")
.Not.Nullable();
Map(x => x.Description, "VDES24")
.Not.Nullable();
Map(x => x.Required, "RMAN24")
.Not.Nullable();
References(x => x.RuleHeader)
.Columns("CONO24", "RLID24")
.NotFound.Ignore()
.Nullable();
}
When I try and add a new object into the RuleVariables IList of RulesEngineHeader and update, I get the error
Batch update returned unexpected row count from update;
actual row count: 0; expected: 1
When I look at my SQL, I’m seeing this:
SELECT rulevariab0_.CONO24 as CONO1_1_,
rulevariab0_.RLID24 as RLID2_1_,
rulevariab0_.RVAR24 as RVAR3_1_,
rulevariab0_.CONO24 as CONO1_1_0_,
rulevariab0_.RLID24 as RLID2_1_0_,
rulevariab0_.RVAR24 as RVAR3_1_0_,
rulevariab0_.VTYP24 as VTYP4_1_0_,
rulevariab0_.VDES24 as VDES5_1_0_,
rulevariab0_.RMAN24 as RMAN6_1_0_
FROM LIOEP024 rulevariab0_
WHERE rulevariab0_.CONO24 = 'LO' /* @p0 */ <-- KEY FIELD
and rulevariab0_.RLID24 = 'Test' /* @p1 */ <-- KEY FIELD
The where clause only contains 2 of the 3 key fields that I defined, so it’s finding the record and trying to update, but then the update looks like this:
UPDATE LIOEP024
SET CONO24 = 'LO' /* @p0_0 */,
RLID24 = 'Test' /* @p1_0 */
WHERE CONO24 = 'LO' /* @p2_0 */ <-- KEY FIELD
AND RLID24 = 'Test' /* @p3_0 */ <-- KEY FIELD
AND RVAR24 = 'Some Name' /* @p4_0 */ <-- KEY FIELD
As you can see, it’s using all 3 of the key fields. It should be doing an insert here instead, but since the select above found the record, it thinks it should do an update, which is returning 0 records.
Any ideas what I’m doing wrong here?
You are using a composite key for RuleVariable. NHibernate has no way of knowing whether your RuleVariable is a new instance or an existing one. If you used a generated id like identity, then it could tell by checking whether the id was > 0.
You need to tell NHibernate that your new RuleVariable is a new instance, ie. you need to persist the RuleVariable before you save the Header, to do so, call session.Save(variable)