forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIPersistenceContext.cs
413 lines (337 loc) · 17.5 KB
/
IPersistenceContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
using System.Collections;
using System.Collections.Generic;
using Iesi.Collections;
using NHibernate.Collection;
using NHibernate.Engine.Loading;
using NHibernate.Persister.Collection;
using NHibernate.Persister.Entity;
using NHibernate.Proxy;
namespace NHibernate.Engine
{
/// <summary>
/// Holds the state of the persistence context, including the
/// first-level cache, entries, snapshots, proxies, etc.
/// </summary>
public interface IPersistenceContext
{
bool IsStateless { get;}
/// <summary>
/// Get the session to which this persistence context is bound.
/// </summary>
ISessionImplementor Session { get;}
/// <summary>
/// Retrieve this persistence context's managed load context.
/// </summary>
LoadContexts LoadContexts { get;}
/// <summary>
/// Get the <tt>BatchFetchQueue</tt>, instantiating one if necessary.
/// </summary>
BatchFetchQueue BatchFetchQueue { get;}
/// <summary> Retrieve the set of EntityKeys representing nullifiable references</summary>
ISet NullifiableEntityKeys { get;}
/// <summary> Get the mapping from key value to entity instance</summary>
IDictionary<EntityKey, object> EntitiesByKey { get;}
/// <summary> Get the mapping from entity instance to entity entry</summary>
IDictionary EntityEntries { get;}
/// <summary> Get the mapping from collection instance to collection entry</summary>
IDictionary CollectionEntries { get;}
/// <summary> Get the mapping from collection key to collection instance</summary>
IDictionary<CollectionKey, IPersistentCollection> CollectionsByKey { get;}
/// <summary> How deep are we cascaded?</summary>
int CascadeLevel { get;}
/// <summary>Is a flush cycle currently in process?</summary>
/// <remarks>Called before and after the flushcycle</remarks>
bool Flushing { get; set;}
/// <summary>
/// The read-only status for entities (and proxies) loaded into this persistence context.
/// </summary>
/// <remarks>
/// <para>
/// When a proxy is initialized, the loaded entity will have the same read-only
/// setting as the uninitialized proxy has, regardless of the persistence context's
/// current setting.
/// </para>
/// <para>
/// To change the read-only setting for a particular entity or proxy that is already
/// in the current persistence context, use <see cref="IPersistenceContext.SetReadOnly(object, bool)" />.
/// </para>
/// </remarks>
/// <seealso cref="IPersistenceContext.IsReadOnly(object)" />
/// <seealso cref="IPersistenceContext.SetReadOnly(object, bool)" />
bool DefaultReadOnly { get; set; }
/// <summary> Add a collection which has no owner loaded</summary>
void AddUnownedCollection(CollectionKey key, IPersistentCollection collection);
/// <summary>
/// Get and remove a collection whose owner is not yet loaded,
/// when its owner is being loaded
/// </summary>
IPersistentCollection UseUnownedCollection(CollectionKey key);
/// <summary> Clear the state of the persistence context</summary>
void Clear();
/// <summary>False if we know for certain that all the entities are read-only</summary>
bool HasNonReadOnlyEntities { get;}
/// <summary> Set the status of an entry</summary>
void SetEntryStatus(EntityEntry entry, Status status);
/// <summary> Called after transactions end</summary>
void AfterTransactionCompletion();
/// <summary>
/// Get the current state of the entity as known to the underlying
/// database, or null if there is no corresponding row
/// </summary>
object[] GetDatabaseSnapshot(object id, IEntityPersister persister);
/// <summary>
/// Retrieve the cached database snapshot for the requested entity key.
/// </summary>
/// <param name="key">The entity key for which to retrieve the cached snapshot </param>
/// <returns> The cached snapshot </returns>
/// <remarks>
/// <list type="bullet">
/// <listheader><description>This differs from <see cref="GetDatabaseSnapshot"/> is two important respects:</description></listheader>
/// <item><description>no snapshot is obtained from the database if not already cached</description></item>
/// <item><description>an entry of NO_ROW here is interpreted as an exception</description></item>
/// </list>
/// </remarks>
object[] GetCachedDatabaseSnapshot(EntityKey key);
/// <summary>
/// Get the values of the natural id fields as known to the underlying
/// database, or null if the entity has no natural id or there is no
/// corresponding row.
/// </summary>
object[] GetNaturalIdSnapshot(object id, IEntityPersister persister);
/// <summary> Add a canonical mapping from entity key to entity instance</summary>
void AddEntity(EntityKey key, object entity);
/// <summary>
/// Get the entity instance associated with the given <tt>EntityKey</tt>
/// </summary>
object GetEntity(EntityKey key);
/// <summary> Is there an entity with the given key in the persistence context</summary>
bool ContainsEntity(EntityKey key);
/// <summary>
/// Remove an entity from the session cache, also clear
/// up other state associated with the entity, all except
/// for the <tt>EntityEntry</tt>
/// </summary>
object RemoveEntity(EntityKey key);
/// <summary> Get an entity cached by unique key</summary>
object GetEntity(EntityUniqueKey euk);
/// <summary> Add an entity to the cache by unique key</summary>
void AddEntity(EntityUniqueKey euk, object entity);
/// <summary>
/// Retrieve the EntityEntry representation of the given entity.
/// </summary>
/// <param name="entity">The entity for which to locate the EntityEntry. </param>
/// <returns> The EntityEntry for the given entity. </returns>
EntityEntry GetEntry(object entity);
/// <summary> Remove an entity entry from the session cache</summary>
EntityEntry RemoveEntry(object entity);
/// <summary> Is there an EntityEntry for this instance?</summary>
bool IsEntryFor(object entity);
/// <summary> Get the collection entry for a persistent collection</summary>
CollectionEntry GetCollectionEntry(IPersistentCollection coll);
/// <summary> Adds an entity to the internal caches.</summary>
EntityEntry AddEntity(object entity, Status status, object[] loadedState, EntityKey entityKey, object version,
LockMode lockMode, bool existsInDatabase, IEntityPersister persister,
bool disableVersionIncrement, bool lazyPropertiesAreUnfetched);
/// <summary>
/// Generates an appropriate EntityEntry instance and adds it
/// to the event source's internal caches.
/// </summary>
EntityEntry AddEntry(object entity, Status status, object[] loadedState, object rowId, object id, object version,
LockMode lockMode, bool existsInDatabase, IEntityPersister persister, bool disableVersionIncrement,
bool lazyPropertiesAreUnfetched);
/// <summary> Is the given collection associated with this persistence context?</summary>
bool ContainsCollection(IPersistentCollection collection);
/// <summary> Is the given proxy associated with this persistence context?</summary>
bool ContainsProxy(INHibernateProxy proxy);
/// <summary>
/// Takes the given object and, if it represents a proxy, reassociates it with this event source.
/// </summary>
/// <param name="value">The possible proxy to be reassociated. </param>
/// <returns> Whether the passed value represented an actual proxy which got initialized. </returns>
bool ReassociateIfUninitializedProxy(object value);
/// <summary>
/// If a deleted entity instance is re-saved, and it has a proxy, we need to
/// reset the identifier of the proxy
/// </summary>
void ReassociateProxy(object value, object id);
/// <summary>
/// Get the entity instance underlying the given proxy, throwing
/// an exception if the proxy is uninitialized. If the given object
/// is not a proxy, simply return the argument.
/// </summary>
object Unproxy(object maybeProxy);
/// <summary>
/// Possibly unproxy the given reference and reassociate it with the current session.
/// </summary>
/// <param name="maybeProxy">The reference to be unproxied if it currently represents a proxy. </param>
/// <returns> The unproxied instance. </returns>
object UnproxyAndReassociate(object maybeProxy);
/// <summary>
/// Attempts to check whether the given key represents an entity already loaded within the
/// current session.
/// </summary>
/// <param name="obj">The entity reference against which to perform the uniqueness check.</param>
/// <param name="key">The entity key.</param>
void CheckUniqueness(EntityKey key, object obj);
/// <summary>
/// If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
/// and overwrite the registration of the old one. This breaks == and occurs only for
/// "class" proxies rather than "interface" proxies. Also init the proxy to point to
/// the given target implementation if necessary.
/// </summary>
/// <param name="proxy">The proxy instance to be narrowed. </param>
/// <param name="persister">The persister for the proxied entity. </param>
/// <param name="key">The internal cache key for the proxied entity. </param>
/// <param name="obj">(optional) the actual proxied entity instance. </param>
/// <returns> An appropriately narrowed instance. </returns>
object NarrowProxy(INHibernateProxy proxy, IEntityPersister persister, EntityKey key, object obj);
/// <summary>
/// Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
/// third argument (the entity associated with the key) if no proxy exists. Init
/// the proxy to the target implementation, if necessary.
/// </summary>
object ProxyFor(IEntityPersister persister, EntityKey key, object impl);
/// <summary>
/// Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
/// argument (the entity associated with the key) if no proxy exists.
/// (slower than the form above)
/// </summary>
object ProxyFor(object impl);
/// <summary> Get the entity that owns this persistent collection</summary>
object GetCollectionOwner(object key, ICollectionPersister collectionPersister);
/// <summary> Get the entity that owned this persistent collection when it was loaded </summary>
/// <param name="collection">The persistent collection </param>
/// <returns>
/// The owner if its entity ID is available from the collection's loaded key
/// and the owner entity is in the persistence context; otherwise, returns null
/// </returns>
object GetLoadedCollectionOwnerOrNull(IPersistentCollection collection);
/// <summary> Get the ID for the entity that owned this persistent collection when it was loaded </summary>
/// <param name="collection">The persistent collection </param>
/// <returns> the owner ID if available from the collection's loaded key; otherwise, returns null </returns>
object GetLoadedCollectionOwnerIdOrNull(IPersistentCollection collection);
/// <summary> add a collection we just loaded up (still needs initializing)</summary>
void AddUninitializedCollection(ICollectionPersister persister, IPersistentCollection collection, object id);
/// <summary> add a detached uninitialized collection</summary>
void AddUninitializedDetachedCollection(ICollectionPersister persister, IPersistentCollection collection);
/// <summary>
/// Add a new collection (ie. a newly created one, just instantiated by the
/// application, with no database state or snapshot)
/// </summary>
/// <param name="collection">The collection to be associated with the persistence context </param>
/// <param name="persister"></param>
void AddNewCollection(ICollectionPersister persister, IPersistentCollection collection);
/// <summary>
/// add an (initialized) collection that was created by another session and passed
/// into update() (ie. one with a snapshot and existing state on the database)
/// </summary>
void AddInitializedDetachedCollection(ICollectionPersister collectionPersister, IPersistentCollection collection);
/// <summary> add a collection we just pulled out of the cache (does not need initializing)</summary>
CollectionEntry AddInitializedCollection(ICollectionPersister persister, IPersistentCollection collection, object id);
/// <summary> Get the collection instance associated with the <tt>CollectionKey</tt></summary>
IPersistentCollection GetCollection(CollectionKey collectionKey);
/// <summary>
/// Register a collection for non-lazy loading at the end of the two-phase load
/// </summary>
void AddNonLazyCollection(IPersistentCollection collection);
/// <summary>
/// Force initialization of all non-lazy collections encountered during
/// the current two-phase load (actually, this is a no-op, unless this
/// is the "outermost" load)
/// </summary>
void InitializeNonLazyCollections();
/// <summary> Get the <tt>PersistentCollection</tt> object for an array</summary>
IPersistentCollection GetCollectionHolder(object array);
/// <summary> Register a <tt>PersistentCollection</tt> object for an array.
/// Associates a holder with an array - MUST be called after loading
/// array, since the array instance is not created until endLoad().
/// </summary>
void AddCollectionHolder(IPersistentCollection holder);
/// <summary>
/// Remove the mapping of collection to holder during eviction of the owning entity
/// </summary>
IPersistentCollection RemoveCollectionHolder(object array);
/// <summary> Get the snapshot of the pre-flush collection state</summary>
object GetSnapshot(IPersistentCollection coll);
/// <summary>
/// Get the collection entry for a collection passed to filter,
/// which might be a collection wrapper, an array, or an unwrapped
/// collection. Return null if there is no entry.
/// </summary>
CollectionEntry GetCollectionEntryOrNull(object collection);
/// <summary> Get an existing proxy by key</summary>
object GetProxy(EntityKey key);
/// <summary> Add a proxy to the session cache</summary>
void AddProxy(EntityKey key, INHibernateProxy proxy);
/// <summary> Remove a proxy from the session cache</summary>
object RemoveProxy(EntityKey key);
/// <summary> Called before cascading</summary>
int IncrementCascadeLevel();
/// <summary> Called after cascading</summary>
int DecrementCascadeLevel();
/// <summary> Call this before beginning a two-phase load</summary>
void BeforeLoad();
/// <summary> Call this after finishing a two-phase load</summary>
void AfterLoad();
/// <summary>
/// Search the persistence context for an owner for the child object,
/// given a collection role
/// </summary>
object GetOwnerId(string entity, string property, object childObject, IDictionary mergeMap);
/// <summary>
/// Search the persistence context for an index of the child object, given a collection role
/// </summary>
object GetIndexInOwner(string entity, string property, object childObject, IDictionary mergeMap);
/// <summary>
/// Record the fact that the association belonging to the keyed entity is null.
/// </summary>
void AddNullProperty(EntityKey ownerKey, string propertyName);
/// <summary> Is the association property belonging to the keyed entity null?</summary>
bool IsPropertyNull(EntityKey ownerKey, string propertyName);
/// <summary>
/// Change the read-only status of an entity (or proxy).
/// </summary>
/// <remarks>
/// <para>
/// Read-only entities can be modified, but changes are not persisted. They are not dirty-checked
/// and snapshots of persistent state are not maintained.
/// </para>
/// <para>
/// Immutable entities cannot be made read-only.
/// </para>
/// <para>
/// To set the <em>default</em> read-only setting for entities and proxies that are loaded
/// into the persistence context, see <see cref="IPersistenceContext.DefaultReadOnly" />.
/// </para>
/// </remarks>
/// <param name="entityOrProxy">An entity (or <see cref="NHibernate.Proxy.INHibernateProxy" />).</param>
/// <param name="readOnly">If <c>true</c>, the entity or proxy is made read-only; if <c>false</c>, it is made modifiable.</param>
/// <seealso cref="IPersistenceContext.DefaultReadOnly" />
/// <seealso cref="IPersistenceContext.IsReadOnly(object)" />
void SetReadOnly(object entityOrProxy, bool readOnly);
/// <summary>
/// Is the specified entity (or proxy) read-only?
/// </summary>
/// <param name="entityOrProxy">An entity (or <see cref="NHibernate.Proxy.INHibernateProxy" />)</param>
/// <returns>
/// <c>true</c> if the entity or proxy is read-only, otherwise <c>false</c>.
/// </returns>
/// <seealso cref="IPersistenceContext.DefaultReadOnly" />
/// <seealso cref="IPersistenceContext.SetReadOnly(object, bool)" />
bool IsReadOnly(object entityOrProxy);
void ReplaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, object generatedId);
/// <summary>Is in a two-phase load? </summary>
bool IsLoadFinished { get; }
/// <summary>
/// Add child/parent relation to cache for cascading operations
/// </summary>
/// <param name="child">The child.</param>
/// <param name="parent">The parent.</param>
void AddChildParent(object child, object parent);
/// <summary>
/// Remove child/parent relation from cache
/// </summary>
/// <param name="child">The child.</param>
void RemoveChildParent(object child);
}
}