forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEntityIdentityInsertAction.cs
148 lines (132 loc) · 4.34 KB
/
EntityIdentityInsertAction.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
using System;
using System.Diagnostics;
using NHibernate.Engine;
using NHibernate.Event;
using NHibernate.Persister.Entity;
namespace NHibernate.Action
{
[Serializable]
public sealed partial class EntityIdentityInsertAction : AbstractEntityInsertAction
{
private readonly bool isDelayed;
private readonly EntityKey delayedEntityKey;
//private CacheEntry cacheEntry;
private object generatedId;
public EntityIdentityInsertAction(object[] state, object instance, IEntityPersister persister, ISessionImplementor session, bool isDelayed)
: base(null, state, instance, persister, session)
{
this.isDelayed = isDelayed;
delayedEntityKey = this.isDelayed
? Session.GenerateEntityKey(new DelayedPostInsertIdentifier(), Persister)
: null;
}
public object GeneratedId
{
get { return generatedId; }
}
public EntityKey DelayedEntityKey
{
get { return delayedEntityKey; }
}
protected internal override bool HasPostCommitEventListeners
{
get
{
return Session.Listeners.PostCommitInsertEventListeners.Length > 0;
}
}
public override void Execute()
{
IEntityPersister persister = Persister;
object instance = Instance;
bool statsEnabled = Session.Factory.Statistics.IsStatisticsEnabled;
Stopwatch stopwatch = null;
if (statsEnabled)
{
stopwatch = Stopwatch.StartNew();
}
bool veto = PreInsert();
// Don't need to lock the cache here, since if someone
// else inserted the same pk first, the insert would fail
if (!veto)
{
generatedId = persister.Insert(State, instance, Session);
if (persister.HasInsertGeneratedProperties)
{
persister.ProcessInsertGeneratedProperties(generatedId, instance, State, Session);
}
//need to do that here rather than in the save event listener to let
//the post insert events to have a id-filled entity when IDENTITY is used (EJB3)
persister.SetIdentifier(instance, generatedId);
}
//TODO from H3.2 : this bit actually has to be called after all cascades!
// but since identity insert is called *synchronously*,
// instead of asynchronously as other actions, it isn't
/*if ( persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
cacheEntry = new CacheEntry(object, persister, session);
persister.getCache().insert(generatedId, cacheEntry);
}*/
PostInsert();
if (statsEnabled && !veto)
{
stopwatch.Stop();
Session.Factory.StatisticsImplementor.InsertEntity(Persister.EntityName, stopwatch.Elapsed);
}
}
private void PostInsert()
{
if (isDelayed)
{
Session.PersistenceContext.ReplaceDelayedEntityIdentityInsertKeys(delayedEntityKey, generatedId);
}
IPostInsertEventListener[] postListeners = Session.Listeners.PostInsertEventListeners;
if (postListeners.Length > 0)
{
PostInsertEvent postEvent = new PostInsertEvent(Instance, generatedId, State, Persister, (IEventSource)Session);
foreach (IPostInsertEventListener listener in postListeners)
{
listener.OnPostInsert(postEvent);
}
}
}
private void PostCommitInsert()
{
IPostInsertEventListener[] postListeners = Session.Listeners.PostCommitInsertEventListeners;
if (postListeners.Length > 0)
{
var postEvent = new PostInsertEvent(Instance, generatedId, State, Persister, (IEventSource) Session);
foreach (IPostInsertEventListener listener in postListeners)
{
listener.OnPostInsert(postEvent);
}
}
}
private bool PreInsert()
{
IPreInsertEventListener[] preListeners = Session.Listeners.PreInsertEventListeners;
bool veto = false;
if (preListeners.Length > 0)
{
var preEvent = new PreInsertEvent(Instance, null, State, Persister, (IEventSource) Session);
foreach (IPreInsertEventListener listener in preListeners)
{
veto |= listener.OnPreInsert(preEvent);
}
}
return veto;
}
protected override void AfterTransactionCompletionProcessImpl(bool success)
{
//TODO Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
//TODO from H3.2: reenable if we also fix the above todo
/*EntityPersister persister = getEntityPersister();
if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
}*/
if (success)
{
PostCommitInsert();
}
}
}
}