Skip to content

Commit 2d6e3e9

Browse files
committed
fix for GRAILS-5158 "Possible NPE in ClosureEventTriggeringInterceptor if entity hasn't metaClass property (entity.metaClass==null)"
1 parent fc7a108 commit 2d6e3e9

File tree

1 file changed

+64
-58
lines changed

1 file changed

+64
-58
lines changed

src/groovy/org/codehaus/groovy/grails/orm/hibernate/support/ClosureEventTriggeringInterceptor.groovy

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ClosureEventTriggeringInterceptor extends SaveOrUpdateEventListener implem
6565
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
6666

6767
def entity = event.getObject()
68-
if(entity) {
68+
if(entity && entity.metaClass) {
6969
boolean newEntity = !event.session.contains(entity)
7070
if(newEntity) {
7171
triggerEvent(BEFORE_INSERT_EVENT, entity, null)
@@ -104,10 +104,12 @@ class ClosureEventTriggeringInterceptor extends SaveOrUpdateEventListener implem
104104

105105
public void onPreLoad(PreLoadEvent event) {
106106
def entity = event.getEntity()
107-
if(entity.metaClass.hasProperty(entity, ONLOAD_EVENT))
108-
triggerEvent(ONLOAD_EVENT, event.entity, event)
109-
else if(entity.metaClass.hasProperty(entity, BEFORE_LOAD_EVENT))
110-
triggerEvent(BEFORE_LOAD_EVENT, event.entity, event)
107+
if (entity.metaClass) {
108+
if(entity.metaClass.hasProperty(entity, ONLOAD_EVENT))
109+
triggerEvent(ONLOAD_EVENT, event.entity, event)
110+
else if(entity.metaClass.hasProperty(entity, BEFORE_LOAD_EVENT))
111+
triggerEvent(BEFORE_LOAD_EVENT, event.entity, event)
112+
}
111113
}
112114

113115
public void onPostLoad(PostLoadEvent event) {
@@ -125,16 +127,19 @@ class ClosureEventTriggeringInterceptor extends SaveOrUpdateEventListener implem
125127

126128
def result = triggerEvent(BEFORE_UPDATE_EVENT, event.entity, event)
127129

128-
Mapping m = GrailsDomainBinder.getMapping(entity.getClass())
129-
boolean shouldTimestamp = m && !m.autoTimestamp ? false : true
130-
MetaProperty property = entity.metaClass.hasProperty(entity, GrailsDomainClassProperty.LAST_UPDATED)
131-
if(property && shouldTimestamp) {
130+
if (entity?.metaClass) {
131+
Mapping m = GrailsDomainBinder.getMapping(entity.getClass())
132+
boolean shouldTimestamp = m && !m.autoTimestamp ? false : true
133+
MetaProperty property = entity.metaClass.hasProperty(entity, GrailsDomainClassProperty.LAST_UPDATED)
134+
if(property && shouldTimestamp) {
132135

133-
def now = property.getType().newInstance([System.currentTimeMillis()] as Object[] )
134-
event.getState()[ArrayUtils.indexOf(event.persister.propertyNames, GrailsDomainClassProperty.LAST_UPDATED)] = now;
135-
entity."$property.name" = now
136+
def now = property.getType().newInstance([System.currentTimeMillis()] as Object[] )
137+
event.getState()[ArrayUtils.indexOf(event.persister.propertyNames, GrailsDomainClassProperty.LAST_UPDATED)] = now;
138+
entity."$property.name" = now
139+
}
136140
}
137141

142+
138143
if(!entity.validate(deepValidate:false)) {
139144
result = true
140145
}
@@ -162,55 +167,56 @@ class ClosureEventTriggeringInterceptor extends SaveOrUpdateEventListener implem
162167

163168
private boolean triggerEvent(String event, entity, Object eventObject) {
164169
def result = false
165-
if(entity.metaClass.hasProperty(entity, event)) {
166-
def callable = entity."$event"
167-
if(callable instanceof Closure) {
168-
callable.resolveStrategy = Closure.DELEGATE_FIRST
169-
callable.delegate = entity
170-
result = callable.call()
171-
if(result instanceof Boolean) result = !result
172-
else {
173-
result = false
174-
}
175-
}
176-
177-
if(eventObject instanceof PreUpdateEvent) {
178-
PreUpdateEvent updateEvent = eventObject
179-
EntityPersister persister = updateEvent.persister
180-
def propertyNames = persister.propertyNames.toList()
181-
def state = updateEvent.state
182-
for(p in propertyNames) {
183-
if(['version','id'].contains(p)) continue
184-
def i = propertyNames.indexOf(p)
185-
def value = entity."$p"
186-
state[i] = value
187-
persister.setPropertyValue(entity,i,value,EntityMode.POJO)
188-
}
189-
}
190-
else if(eventObject instanceof SaveOrUpdateEvent) {
191-
SaveOrUpdateEvent updateEvent = eventObject
192-
193-
if(updateEvent.session.contains(entity)) {
194-
EntityEntry entry = updateEvent.getEntry()
195-
if(entry) {
196-
def propertyNames = entry.persister.propertyNames.toList()
197-
def state = entry.loadedState
198-
for(p in propertyNames) {
199-
if(['version','id'].contains(p)) continue
200-
def i = propertyNames.indexOf(p)
201-
def value = entity."$p"
202-
state[i] = value
203-
entry.persister.setPropertyValue(entity,i,value,EntityMode.POJO)
204-
}
205-
206-
}
207-
}
208-
}
209-
}
170+
if (entity?.metaClass) {
171+
if(entity.metaClass.hasProperty(entity, event)) {
172+
def callable = entity."$event"
173+
if(callable instanceof Closure) {
174+
callable.resolveStrategy = Closure.DELEGATE_FIRST
175+
callable.delegate = entity
176+
result = callable.call()
177+
if(result instanceof Boolean) result = !result
178+
else {
179+
result = false
180+
}
181+
}
182+
183+
if(eventObject instanceof PreUpdateEvent) {
184+
PreUpdateEvent updateEvent = eventObject
185+
EntityPersister persister = updateEvent.persister
186+
def propertyNames = persister.propertyNames.toList()
187+
def state = updateEvent.state
188+
for(p in propertyNames) {
189+
if(['version','id'].contains(p)) continue
190+
def i = propertyNames.indexOf(p)
191+
def value = entity."$p"
192+
state[i] = value
193+
persister.setPropertyValue(entity,i,value,EntityMode.POJO)
194+
}
195+
}
196+
else if(eventObject instanceof SaveOrUpdateEvent) {
197+
SaveOrUpdateEvent updateEvent = eventObject
198+
199+
if(updateEvent.session.contains(entity)) {
200+
EntityEntry entry = updateEvent.getEntry()
201+
if(entry) {
202+
def propertyNames = entry.persister.propertyNames.toList()
203+
def state = entry.loadedState
204+
for(p in propertyNames) {
205+
if(['version','id'].contains(p)) continue
206+
def i = propertyNames.indexOf(p)
207+
def value = entity."$p"
208+
state[i] = value
209+
entry.persister.setPropertyValue(entity,i,value,EntityMode.POJO)
210+
}
211+
}
212+
}
213+
}
214+
}
215+
}
210216
return result
211217

212218
}
213219

214220

215221

216-
}
222+
}

0 commit comments

Comments
 (0)