private void saveTransientEntity( Object entity, String entityName, Serializable requestedId, EventSource source, Map copyCache) { //this bit is only *really* absolutely necessary for handling //requestedId, but is also good if we merge multiple object //graphs, since it helps ensure uniqueness if ( requestedId == null ) { saveWithGeneratedId( entity, entityName, copyCache, source, false ); } else { saveWithRequestedId( entity, requestedId, entityName, copyCache, source ); } }
entityIsTransient( event, copyCache ); ); else if ( isVersionChanged( entity, source, persister, target ) ) { if ( source.getFactory().getStatistics().isStatisticsEnabled() ) { source.getFactory().getStatistics().optimisticFailure( entityName ); cascadeOnMerge( source, persister, entity, copyCache ); copyValues( persister, entity, target, source, copyCache ); markInterceptorDirty( entity, target, persister );
entityState = getEntityState( entity, event.getEntityName(), entry, source ); entityIsDetached( event, copyCache ); break; case TRANSIENT: entityIsTransient( event, copyCache ); break; case PERSISTENT: entityIsPersistent( event, copyCache ); break; default: //DELETED "deleted instance passed to merge", null, getLoggableName( event.getEntityName(), entity ) );
protected void entityIsPersistent(MergeEvent event, Map copyCache) { LOG.trace( "Ignoring persistent instance" ); //TODO: check that entry.getIdentifier().equals(requestedId) final Object entity = event.getEntity(); final EventSource source = event.getSession(); final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); ( (MergeContext) copyCache ).put( entity, entity, true ); //before cascade! cascadeOnMerge( source, persister, entity, copyCache ); copyValues( persister, entity, entity, source, copyCache ); event.setResult( entity ); }
protected void entityIsTransient(MergeEvent event, Map copyCache) { LOG.trace( "Merging transient instance" ); final Object entity = event.getEntity(); final EventSource source = event.getSession(); final String entityName = event.getEntityName(); final EntityPersister persister = source.getEntityPersister( entityName, entity ); final Serializable id = persister.hasIdentifierProperty() ? persister.getIdentifier( entity, source ) : null; if ( copyCache.containsKey( entity ) ) { persister.setIdentifier( copyCache.get( entity ), id, source ); } else { ( (MergeContext) copyCache ).put( entity, source.instantiate( persister, id ), true ); //before cascade! } final Object copy = copyCache.get( entity ); // cascade first, so that all unsaved objects get their // copy created before we actually copy //cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE); super.cascadeBeforeSave( source, persister, entity, copyCache ); copyValues( persister, entity, copy, source, copyCache, ForeignKeyDirection.FROM_PARENT ); saveTransientEntity( copy, entityName, event.getRequestedId(), source, copyCache ); // cascade first, so that all unsaved objects get their // copy created before we actually copy super.cascadeAfterSave( source, persister, entity, copyCache ); copyValues( persister, entity, copy, source, copyCache, ForeignKeyDirection.TO_PARENT ); event.setResult( copy ); }
private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) { if ( !persister.isVersioned() ) { return false; } // for merging of versioned entities, we consider the version having // been changed only when: // 1) the two version values are different; // *AND* // 2) The target actually represents database state! // // This second condition is a special case which allows // an entity to be merged during the same transaction // (though during a seperate operation) in which it was // originally persisted/saved boolean changed = !persister.getVersionType().isSame( persister.getVersion( target ), persister.getVersion( entity ) ); // TODO : perhaps we should additionally require that the incoming entity // version be equivalent to the defined unsaved-value? return changed && existsInDatabase( target, source, persister ); }
/** * Perform any cascades needed as part of this copy event. * * @param source The merge event being processed. * @param persister The persister of the entity being copied. * @param entity The entity being copied. * @param copyCache A cache of already copied instance. */ protected void cascadeOnMerge( final EventSource source, final EntityPersister persister, final Object entity, final Map copyCache ) { source.getPersistenceContext().incrementCascadeLevel(); try { Cascade.cascade( getCascadeAction(), CascadePoint.BEFORE_MERGE, source, persister, entity, copyCache ); } finally { source.getPersistenceContext().decrementCascadeLevel(); } }
new DefaultMergeEventListener(), listenerArray );
@Override protected Serializable saveWithRequestedId( Object entity, Serializable requestedId, String entityName, Object anything, EventSource source) { callbackHandler.preCreate( entity ); return super.saveWithRequestedId( entity, requestedId, entityName, anything, source ); }
@Override protected Serializable saveWithGeneratedId( Object entity, String entityName, Object anything, EventSource source, boolean requiresImmediateIdAccess) { callbackHandler.preCreate( entity ); return super.saveWithGeneratedId( entity, entityName, anything, source, requiresImmediateIdAccess ); } }
protected void entityIsPersistent(MergeEvent event, Map copyCache) { LOG.trace( "Ignoring persistent instance" ); //TODO: check that entry.getIdentifier().equals(requestedId) final Object entity = event.getEntity(); final EventSource source = event.getSession(); final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); ( ( EventCache ) copyCache ).put( entity, entity, true ); //before cascade! cascadeOnMerge(source, persister, entity, copyCache); copyValues(persister, entity, entity, source, copyCache); event.setResult(entity); }
protected void entityIsTransient(MergeEvent event, Map copyCache) { LOG.trace( "Merging transient instance" ); final Object entity = event.getEntity(); final EventSource source = event.getSession(); final String entityName = event.getEntityName(); final EntityTypeDescriptor entityDescriptor = source.getEntityDescriptor( entityName, entity ); final Object id = EntityIdentifierSimple.class.isInstance( entityDescriptor.getHierarchy().getIdentifierDescriptor() ) ? entityDescriptor.getIdentifier( entity, source ) : null; if ( copyCache.containsKey( entity ) ) { entityDescriptor.setIdentifier( copyCache.get( entity ), id, source ); } else { ( (MergeContext) copyCache ).put( entity, source.instantiate( entityDescriptor, id ), true ); //before cascade! } final Object copy = copyCache.get( entity ); // cascade first, so that all unsaved objects get their // copy created before we actually copy //cascadeOnMerge(event, entityDescriptor, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE); super.cascadeBeforeSave( source, entityDescriptor, entity, copyCache ); copyValues( entityDescriptor, entity, copy, source, copyCache, ForeignKeyDirection.FROM_PARENT ); saveTransientEntity( copy, entityName, event.getRequestedId(), source, copyCache ); // cascade first, so that all unsaved objects get their // copy created before we actually copy super.cascadeAfterSave( source, entityDescriptor, entity, copyCache ); copyValues( entityDescriptor, entity, copy, source, copyCache, ForeignKeyDirection.TO_PARENT ); event.setResult( copy ); }
private boolean isVersionChanged(Object entity, EventSource source, EntityTypeDescriptor entityDescriptor, Object target) { if ( entityDescriptor.getHierarchy().getVersionDescriptor() == null ) { // not versioned, obviously the version did not change :) return false; } // for merging of versioned entities, we consider the version having // been changed only when: // 1) the two version values are different; // *AND* // 2) The target actually represents database state! // // This second condition is a special case which allows // an entity to be merged during the same transaction // (though during a seperate operation) in which it was // originally persisted/saved boolean changed = !Objects.equals( entityDescriptor.getVersion( target ), entityDescriptor.getVersion( entity ) ); // TODO : perhaps we should additionally require that the incoming entity // version be equivalent to the defined unsaved-value? return changed && existsInDatabase( target, source, entityDescriptor ); }
/** * Perform any cascades needed as part of this copy event. * * @param source The merge event being processed. * @param entityDescriptor The entityDescriptor of the entity being copied. * @param entity The entity being copied. * @param copyCache A cache of already copied instance. */ protected void cascadeOnMerge( final EventSource source, final EntityTypeDescriptor entityDescriptor, final Object entity, final Map copyCache ) { source.getPersistenceContext().incrementCascadeLevel(); try { Cascade.cascade( getCascadeAction(), CascadePoint.BEFORE_MERGE, source, entityDescriptor, entity, copyCache ); } finally { source.getPersistenceContext().decrementCascadeLevel(); } }
new DefaultMergeEventListener(), workMap );
entityIsTransient(event, copyCache); ); else if ( isVersionChanged( entity, source, persister, target ) ) { if ( source.getFactory().getStatistics().isStatisticsEnabled() ) { source.getFactory().getStatisticsImplementor() cascadeOnMerge(source, persister, entity, copyCache); copyValues(persister, entity, target, source, copyCache); markInterceptorDirty( entity, target, persister );
entityState = getEntityState( entity, event.getEntityName(), entry, source ); entityIsDetached(event, copyCache); break; case TRANSIENT: entityIsTransient(event, copyCache); break; case PERSISTENT: entityIsPersistent(event, copyCache); break; default: //DELETED "deleted instance passed to merge", null, getLoggableName( event.getEntityName(), entity ) );
private void saveTransientEntity( Object entity, String entityName, Serializable requestedId, EventSource source, Map copyCache) { //this bit is only *really* absolutely necessary for handling //requestedId, but is also good if we merge multiple object //graphs, since it helps ensure uniqueness if ( requestedId == null ) { saveWithGeneratedId( entity, entityName, copyCache, source, false ); } else { saveWithRequestedId( entity, requestedId, entityName, copyCache, source ); } }
protected void entityIsPersistent(MergeEvent event, Map copyCache) { LOG.trace( "Ignoring persistent instance" ); //TODO: check that entry.getIdentifier().equals(requestedId) final Object entity = event.getEntity(); final EventSource source = event.getSession(); final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); ( ( EventCache ) copyCache ).put( entity, entity, true ); //before cascade! cascadeOnMerge(source, persister, entity, copyCache); copyValues(persister, entity, entity, source, copyCache); event.setResult(entity); }
protected void entityIsTransient(MergeEvent event, Map copyCache) { LOG.trace( "Merging transient instance" ); final Object entity = event.getEntity(); final EventSource source = event.getSession(); final String entityName = event.getEntityName(); final EntityPersister persister = source.getEntityPersister( entityName, entity ); final Serializable id = persister.hasIdentifierProperty() ? persister.getIdentifier( entity, source ) : null; if ( copyCache.containsKey( entity ) ) { persister.setIdentifier( copyCache.get( entity ), id, source ); } else { ( ( EventCache ) copyCache ).put( entity, source.instantiate( persister, id ), true ); //before cascade! } final Object copy = copyCache.get( entity ); // cascade first, so that all unsaved objects get their // copy created before we actually copy //cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE); super.cascadeBeforeSave(source, persister, entity, copyCache); copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT); saveTransientEntity( copy, entityName, event.getRequestedId(), source, copyCache ); // cascade first, so that all unsaved objects get their // copy created before we actually copy super.cascadeAfterSave(source, persister, entity, copyCache); copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_TO_PARENT); event.setResult( copy ); }