Skip to content

Instantly share code, notes, and snippets.

@gunnarmorling
Created October 16, 2014 08:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gunnarmorling/4102d7446e79b036b024 to your computer and use it in GitHub Desktop.
Save gunnarmorling/4102d7446e79b036b024 to your computer and use it in GitHub Desktop.
private static class OgmPersistEventListener extends DefaultPersistEventListener {
/**
* Performs all the actual work needed to save an entity (well to get the save moved to
* the execution queue).
*
* @param entity The entity to be saved
* @param key The id to be used for saving the entity (or null, in the case of identity columns)
* @param persister The entity's persister instance.
* @param useIdentityColumn Should an identity column be used for id generation?
* @param anything Generally cascade-specific information.
* @param source The session which is the source of the current event.
* @param requiresImmediateIdAccess Is access to the identifier required immediately
* after the completion of the save? persist(), for example, does not require this...
*
* @return The id used to save the entity; may be null depending on the
* type of id generator used and the requiresImmediateIdAccess value
*/
@Override
protected Serializable performSaveOrReplicate(
Object entity,
EntityKey key,
EntityPersister persister,
boolean useIdentityColumn,
Object anything,
EventSource source,
boolean requiresImmediateIdAccess) {
Serializable id = key == null ? null : key.getIdentifier();
boolean inTxn = source.getTransactionCoordinator().isTransactionInProgress();
boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
// Put a placeholder in entries, so we don't recurse back and try to save() the
// same object again. QUESTION: should this be done before onSave() is called?
// likewise, should it be done before onUpdate()?
EntityEntry original = source.getPersistenceContext().addEntry(
entity,
Status.SAVING,
null,
null,
id,
null,
LockMode.WRITE,
useIdentityColumn,
persister,
false,
false
);
cascadeBeforeSave( source, persister, entity, anything );
Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( anything ), source );
Type[] types = persister.getPropertyTypes();
boolean substitute = substituteValuesIfNecessary( entity, id, values, persister, source );
if ( persister.hasCollections() ) {
substitute = substitute || visitCollectionsBeforeSave( entity, id, values, types, source );
}
if ( substitute ) {
persister.setPropertyValues( entity, values );
}
TypeHelper.deepCopy(
values,
types,
persister.getPropertyUpdateability(),
values,
source
);
AbstractEntityInsertAction insert = addInsertAction(
values, id, entity, persister, useIdentityColumn, source, shouldDelayIdentityInserts
);
// postpone initializing id in case the insert has non-nullable transient dependencies
// that are not resolved until cascadeAfterSave() is executed
cascadeAfterSave( source, persister, entity, anything );
if ( useIdentityColumn && insert.isEarlyInsert() ) {
if ( !EntityIdentityInsertAction.class.isInstance( insert ) ) {
throw new IllegalStateException(
"Insert should be using an identity column, but action is of unexpected type: " +
insert.getClass().getName()
);
}
id = ((EntityIdentityInsertAction) insert).getGeneratedId();
insert.handleNaturalIdPostSaveNotifications( id );
}
markInterceptorDirty( entity, persister, source );
EntityEntry newEntry = source.getPersistenceContext().getEntry( entity );
if ( newEntry != original ) {
OgmEntityEntryState ogmEntityState = newEntry.getExtraState( OgmEntityEntryState.class );
if ( ogmEntityState == null ) {
newEntry.addExtraState( original.getExtraState( OgmEntityEntryState.class ) );
}
}
return id;
}
private AbstractEntityInsertAction addInsertAction(
Object[] values,
Serializable id,
Object entity,
EntityPersister persister,
boolean useIdentityColumn,
EventSource source,
boolean shouldDelayIdentityInserts) {
if ( useIdentityColumn ) {
EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
values, entity, persister, isVersionIncrementDisabled(), source, shouldDelayIdentityInserts
);
source.getActionQueue().addAction( insert );
return insert;
}
else {
Object version = Versioning.getVersion( values, persister );
EntityInsertAction insert = new EntityInsertAction(
id, values, entity, version, persister, isVersionIncrementDisabled(), source
);
source.getActionQueue().addAction( insert );
return insert;
}
}
private void markInterceptorDirty(Object entity, EntityPersister persister, EventSource source) {
if ( persister.getInstrumentationMetadata().isInstrumented() ) {
FieldInterceptor interceptor = persister.getInstrumentationMetadata().injectInterceptor(
entity,
persister.getEntityName(),
null,
source
);
interceptor.dirty();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment