下面列出了org.hibernate.type.TypeHelper#deepCopy ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private Object[] createDeletedState(EntityPersister persister, Object[] currentState, EventSource session) {
Type[] propTypes = persister.getPropertyTypes();
final Object[] deletedState = new Object[propTypes.length];
// TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session );
boolean[] copyability = new boolean[propTypes.length];
java.util.Arrays.fill( copyability, true );
TypeHelper.deepCopy( currentState, propTypes, copyability, deletedState, session );
return deletedState;
}
private Object[] createDeletedState(EntityPersister persister, Object[] currentState, EventSource session) {
Type[] propTypes = persister.getPropertyTypes();
final Object[] deletedState = new Object[propTypes.length];
// TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session );
boolean[] copyability = new boolean[propTypes.length];
java.util.Arrays.fill( copyability, true );
TypeHelper.deepCopy( currentState, propTypes, copyability, deletedState, session );
return deletedState;
}
private Object convertCacheEntryToEntity(
CacheEntry entry,
Serializable entityId,
EntityPersister persister,
LoadEvent event,
EntityKey entityKey) {
final EventSource session = event.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final EntityPersister subclassPersister;
if ( traceEnabled ) {
LOG.tracef(
"Converting second-level cache entry [%s] into entity : %s",
entry,
MessageHelper.infoString( persister, entityId, factory )
);
}
final Object entity;
subclassPersister = factory.getEntityPersister( entry.getSubclass() );
final Object optionalObject = event.getInstanceToLoad();
entity = optionalObject == null
? session.instantiate( subclassPersister, entityId )
: optionalObject;
// make it circular-reference safe
TwoPhaseLoad.addUninitializedCachedEntity(
entityKey,
entity,
subclassPersister,
LockMode.NONE,
entry.getVersion(),
session
);
final PersistenceContext persistenceContext = session.getPersistenceContext();
final Object[] values;
final Object version;
final boolean isReadOnly;
final Type[] types = subclassPersister.getPropertyTypes();
// initializes the entity by (desired) side-effect
values = ( (StandardCacheEntryImpl) entry ).assemble(
entity, entityId, subclassPersister, session.getInterceptor(), session
);
if ( ( (StandardCacheEntryImpl) entry ).isDeepCopyNeeded() ) {
TypeHelper.deepCopy(
values,
types,
subclassPersister.getPropertyUpdateability(),
values,
session
);
}
version = Versioning.getVersion( values, subclassPersister );
LOG.tracef( "Cached Version : %s", version );
final Object proxy = persistenceContext.getProxy( entityKey );
if ( proxy != null ) {
// there is already a proxy for this impl
// only set the status to read-only if the proxy is read-only
isReadOnly = ( (HibernateProxy) proxy ).getHibernateLazyInitializer().isReadOnly();
}
else {
isReadOnly = session.isDefaultReadOnly();
}
persistenceContext.addEntry(
entity,
( isReadOnly ? Status.READ_ONLY : Status.MANAGED ),
values,
null,
entityId,
version,
LockMode.NONE,
true,
subclassPersister,
false
);
subclassPersister.afterInitialize( entity, session );
persistenceContext.initializeNonLazyCollections();
//PostLoad is needed for EJB3
PostLoadEvent postLoadEvent = event.getPostLoadEvent()
.setEntity( entity )
.setId( entityId )
.setPersister( persister );
for ( PostLoadEventListener listener : postLoadEventListeners( session ) ) {
listener.onPostLoad( postLoadEvent );
}
return entity;
}
/**
* Associates a given entity (either transient or associated with another session) to
* the given session.
*
* @param event The event triggering the re-association
* @param object The entity to be associated
* @param id The id of the entity.
* @param persister The entity's persister instance.
*
* @return An EntityEntry representing the entity within this session.
*/
protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) {
if ( log.isTraceEnabled() ) {
log.tracev(
"Reassociating transient instance: {0}",
MessageHelper.infoString( persister, id, event.getSession().getFactory() )
);
}
final EventSource source = event.getSession();
final EntityKey key = source.generateEntityKey( id, persister );
source.getPersistenceContext().checkUniqueness( key, object );
//get a snapshot
Object[] values = persister.getPropertyValues( object );
TypeHelper.deepCopy(
values,
persister.getPropertyTypes(),
persister.getPropertyUpdateability(),
values,
source
);
Object version = Versioning.getVersion( values, persister );
EntityEntry newEntry = source.getPersistenceContext().addEntity(
object,
( persister.isMutable() ? Status.MANAGED : Status.READ_ONLY ),
values,
key,
version,
LockMode.NONE,
true,
persister,
false
);
new OnLockVisitor( source, id, object ).process( object, persister );
persister.afterReassociate( object, source );
return newEntry;
}
/**
* 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
*/
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 shouldDelayIdentityInserts = shouldDelayIdentityInserts( requiresImmediateIdAccess, source );
// 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
);
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 );
}
EntityEntry newEntry = source.getPersistenceContext().getEntry( entity );
if ( newEntry != original ) {
EntityEntryExtraState extraState = newEntry.getExtraState( EntityEntryExtraState.class );
if ( extraState == null ) {
newEntry.addExtraState( original.getExtraState( EntityEntryExtraState.class ) );
}
}
return id;
}