@@ -81,33 +81,23 @@ public override Task NullSafeSetAsync(DbCommand cmd, object value, int index, IS
81
81
}
82
82
}
83
83
84
- public override Task < object > DisassembleAsync ( object value , ISessionImplementor session , object owner , CancellationToken cancellationToken )
84
+ public override async Task < object > DisassembleAsync ( object value , ISessionImplementor session , object owner , CancellationToken cancellationToken )
85
85
{
86
- if ( cancellationToken . IsCancellationRequested )
87
- {
88
- return Task . FromCanceled < object > ( cancellationToken ) ;
89
- }
90
- try
91
- {
92
- //remember the uk value
86
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
87
+ //remember the uk value
93
88
94
- //This solution would allow us to eliminate the owner arg to disassemble(), but
95
- //what if the collection was null, and then later had elements added? seems unsafe
96
- //session.getPersistenceContext().getCollectionEntry( (PersistentCollection) value ).getKey();
89
+ //This solution would allow us to eliminate the owner arg to disassemble(), but
90
+ //what if the collection was null, and then later had elements added? seems unsafe
91
+ //session.getPersistenceContext().getCollectionEntry( (PersistentCollection) value ).getKey();
97
92
98
- object key = GetKeyOfOwner ( owner , session ) ;
99
- if ( key == null )
100
- {
101
- return Task . FromResult < object > ( null ) ;
102
- }
103
- else
104
- {
105
- return GetPersister ( session ) . KeyType . DisassembleAsync ( key , session , owner , cancellationToken ) ;
106
- }
93
+ object key = await ( GetKeyOfOwnerAsync ( owner , session , cancellationToken ) ) . ConfigureAwait ( false ) ;
94
+ if ( key == null )
95
+ {
96
+ return null ;
107
97
}
108
- catch ( Exception ex )
98
+ else
109
99
{
110
- return Task . FromException < object > ( ex ) ;
100
+ return await ( GetPersister ( session ) . KeyType . DisassembleAsync ( key , session , owner , cancellationToken ) ) . ConfigureAwait ( false ) ;
111
101
}
112
102
}
113
103
@@ -152,20 +142,10 @@ public override Task<object> HydrateAsync(DbDataReader rs, string[] name, ISessi
152
142
}
153
143
}
154
144
155
- public override Task < object > ResolveIdentifierAsync ( object key , ISessionImplementor session , object owner , CancellationToken cancellationToken )
145
+ public override async Task < object > ResolveIdentifierAsync ( object key , ISessionImplementor session , object owner , CancellationToken cancellationToken )
156
146
{
157
- if ( cancellationToken . IsCancellationRequested )
158
- {
159
- return Task . FromCanceled < object > ( cancellationToken ) ;
160
- }
161
- try
162
- {
163
- return ResolveKeyAsync ( GetKeyOfOwner ( owner , session ) , session , owner , cancellationToken ) ;
164
- }
165
- catch ( Exception ex )
166
- {
167
- return Task . FromException < object > ( ex ) ;
168
- }
147
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
148
+ return await ( ResolveKeyAsync ( await ( GetKeyOfOwnerAsync ( owner , session , cancellationToken ) ) . ConfigureAwait ( false ) , session , owner , cancellationToken ) ) . ConfigureAwait ( false ) ;
169
149
}
170
150
171
151
private Task < object > ResolveKeyAsync ( object key , ISessionImplementor session , object owner , CancellationToken cancellationToken )
@@ -310,5 +290,42 @@ public override Task<bool> IsModifiedAsync(object oldHydratedState, object curre
310
290
return Task . FromException < bool > ( ex ) ;
311
291
}
312
292
}
293
+
294
+ /// <summary>
295
+ /// Get the key value from the owning entity instance. It is usually the identifier, but it might be some
296
+ /// other unique key, in the case of a property-ref.
297
+ /// </summary>
298
+ public async Task < object > GetKeyOfOwnerAsync ( object owner , ISessionImplementor session , CancellationToken cancellationToken )
299
+ {
300
+ cancellationToken . ThrowIfCancellationRequested ( ) ;
301
+ var entityEntry = session . PersistenceContext . GetEntry ( owner ) ;
302
+ if ( entityEntry == null )
303
+ {
304
+ // This just handles a particular case of component
305
+ // projection, perhaps get rid of it and throw an exception
306
+ return null ;
307
+ }
308
+
309
+ if ( foreignKeyPropertyName == null )
310
+ {
311
+ return entityEntry . Id ;
312
+ }
313
+
314
+ // TODO: at the point where we are resolving collection references, we don't
315
+ // know if the uk value has been resolved (depends if it was earlier or
316
+ // later in the mapping document) - now, we could try and use e.getStatus()
317
+ // to decide to semiResolve(), trouble is that initializeEntity() reuses
318
+ // the same array for resolved and hydrated values
319
+ var id = entityEntry . LoadedState != null
320
+ ? entityEntry . GetLoadedValue ( foreignKeyPropertyName )
321
+ : entityEntry . Persister . GetPropertyValue ( owner , foreignKeyPropertyName ) ;
322
+ // NOTE VERY HACKISH WORKAROUND!!
323
+ var keyType = GetPersister ( session ) . KeyType ;
324
+ if ( ! keyType . ReturnedClass . IsInstanceOfType ( id ) )
325
+ {
326
+ id = await ( keyType . SemiResolveAsync ( entityEntry . GetLoadedValue ( foreignKeyPropertyName ) , session , owner , cancellationToken ) ) . ConfigureAwait ( false ) ;
327
+ }
328
+ return id ;
329
+ }
313
330
}
314
331
}
0 commit comments