Skip to content

Commit 4febb10

Browse files
committed
ISession.IsDirty() should not throw exception on new ManyToOne object in session
1 parent 8ef2ccd commit 4febb10

File tree

2 files changed

+60
-42
lines changed

2 files changed

+60
-42
lines changed

src/NHibernate/Async/Type/ManyToOneType.cs

+31-19
Original file line numberDiff line numberDiff line change
@@ -135,37 +135,49 @@ private Task<object> AssembleIdAsync(object oid, ISessionImplementor session, Ca
135135
}
136136
}
137137

138-
public override async Task<bool> IsDirtyAsync(object old, object current, ISessionImplementor session, CancellationToken cancellationToken)
138+
public override Task<bool> IsDirtyAsync(object old, object current, ISessionImplementor session, CancellationToken cancellationToken)
139139
{
140-
cancellationToken.ThrowIfCancellationRequested();
141-
if (IsSame(old, current))
140+
if (cancellationToken.IsCancellationRequested)
142141
{
143-
return false;
142+
return Task.FromCanceled<bool>(cancellationToken);
144143
}
144+
return IsDirtyManyToOneAsync(old, current, null, session, cancellationToken);
145+
}
145146

146-
object oldid = await (GetIdentifierAsync(old, session, cancellationToken)).ConfigureAwait(false);
147-
object newid = await (GetIdentifierAsync(current, session, cancellationToken)).ConfigureAwait(false);
148-
return await (GetIdentifierType(session).IsDirtyAsync(oldid, newid, session, cancellationToken)).ConfigureAwait(false);
147+
public override Task<bool> IsDirtyAsync(object old, object current, bool[] checkable, ISessionImplementor session, CancellationToken cancellationToken)
148+
{
149+
if (cancellationToken.IsCancellationRequested)
150+
{
151+
return Task.FromCanceled<bool>(cancellationToken);
152+
}
153+
return IsDirtyManyToOneAsync(old, current, IsAlwaysDirtyChecked ? null : checkable, session, cancellationToken);
149154
}
150155

151-
public override async Task<bool> IsDirtyAsync(object old, object current, bool[] checkable, ISessionImplementor session, CancellationToken cancellationToken)
156+
private async Task<bool> IsDirtyManyToOneAsync(object old, object current, bool[] checkable, ISessionImplementor session, CancellationToken cancellationToken)
152157
{
153158
cancellationToken.ThrowIfCancellationRequested();
154-
if (IsAlwaysDirtyChecked)
159+
if (IsSame(old, current))
160+
{
161+
return false;
162+
}
163+
164+
if (old == null || current == null)
155165
{
156-
return await (IsDirtyAsync(old, current, session, cancellationToken)).ConfigureAwait(false);
166+
return true;
157167
}
158-
else
168+
169+
if (await (ForeignKeys.IsTransientFastAsync(GetAssociatedEntityName(), current, session, cancellationToken)).ConfigureAwait(false) == true)
159170
{
160-
if (IsSame(old, current))
161-
{
162-
return false;
163-
}
164-
165-
object oldid = await (GetIdentifierAsync(old, session, cancellationToken)).ConfigureAwait(false);
166-
object newid = await (GetIdentifierAsync(current, session, cancellationToken)).ConfigureAwait(false);
167-
return await (GetIdentifierType(session).IsDirtyAsync(oldid, newid, checkable, session, cancellationToken)).ConfigureAwait(false);
171+
return true;
168172
}
173+
174+
object oldid = await (GetIdentifierAsync(old, session, cancellationToken)).ConfigureAwait(false);
175+
object newid = await (GetIdentifierAsync(current, session, cancellationToken)).ConfigureAwait(false);
176+
IType identifierType = GetIdentifierType(session);
177+
178+
return checkable == null
179+
? await (identifierType.IsDirtyAsync(oldid, newid, session, cancellationToken)).ConfigureAwait(false)
180+
: await (identifierType.IsDirtyAsync(old, current, checkable, session, cancellationToken)).ConfigureAwait(false);
169181
}
170182
}
171183
}

src/NHibernate/Type/ManyToOneType.cs

+29-23
Original file line numberDiff line numberDiff line change
@@ -181,35 +181,15 @@ public override bool IsAlwaysDirtyChecked
181181

182182
public override bool IsDirty(object old, object current, ISessionImplementor session)
183183
{
184-
if (IsSame(old, current))
185-
{
186-
return false;
187-
}
188-
189-
object oldid = GetIdentifier(old, session);
190-
object newid = GetIdentifier(current, session);
191-
return GetIdentifierType(session).IsDirty(oldid, newid, session);
184+
return IsDirtyManyToOne(old, current, null, session);
192185
}
193186

194187
public override bool IsDirty(object old, object current, bool[] checkable, ISessionImplementor session)
195188
{
196-
if (IsAlwaysDirtyChecked)
197-
{
198-
return IsDirty(old, current, session);
199-
}
200-
else
201-
{
202-
if (IsSame(old, current))
203-
{
204-
return false;
205-
}
206-
207-
object oldid = GetIdentifier(old, session);
208-
object newid = GetIdentifier(current, session);
209-
return GetIdentifierType(session).IsDirty(oldid, newid, checkable, session);
210-
}
189+
return IsDirtyManyToOne(old, current, IsAlwaysDirtyChecked ? null : checkable, session);
211190
}
212191

192+
213193
public override bool IsNullable
214194
{
215195
get { return ignoreNotFound; }
@@ -224,5 +204,31 @@ public override bool[] ToColumnNullness(object value, IMapping mapping)
224204
}
225205
return result;
226206
}
207+
208+
private bool IsDirtyManyToOne(object old, object current, bool[] checkable, ISessionImplementor session)
209+
{
210+
if (IsSame(old, current))
211+
{
212+
return false;
213+
}
214+
215+
if (old == null || current == null)
216+
{
217+
return true;
218+
}
219+
220+
if (ForeignKeys.IsTransientFast(GetAssociatedEntityName(), current, session) == true)
221+
{
222+
return true;
223+
}
224+
225+
object oldid = GetIdentifier(old, session);
226+
object newid = GetIdentifier(current, session);
227+
IType identifierType = GetIdentifierType(session);
228+
229+
return checkable == null
230+
? identifierType.IsDirty(oldid, newid, session)
231+
: identifierType.IsDirty(old, current, checkable, session);
232+
}
227233
}
228234
}

0 commit comments

Comments
 (0)