下面列出了org.hibernate.proxy.LazyInitializer#isUninitialized ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Is the given attribute (by name) loaded? This form must take care to not access the attribute (trigger
* initialization).
*
* @param entity The entity
* @param attributeName The name of the attribute to check
* @param cache The cache we maintain of attribute resolutions
*
* @return The LoadState
*/
public static LoadState isLoadedWithReference(Object entity, String attributeName, MetadataCache cache) {
if ( entity instanceof HibernateProxy ) {
final LazyInitializer li = ( (HibernateProxy) entity ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
// we have an uninitialized proxy, the attribute cannot be loaded
return LoadState.NOT_LOADED;
}
else {
// swap the proxy with target (for proper class name resolution)
entity = li.getImplementation();
}
}
try {
final Class entityClass = entity.getClass();
final Object attributeValue = cache.getClassMetadata( entityClass )
.getAttributeAccess( attributeName )
.extractValue( entity );
return isLoaded( attributeValue );
}
catch (AttributeExtractionException ignore) {
return LoadState.UNKNOWN;
}
}
@Override
public Object unproxy(Object maybeProxy) throws HibernateException {
if ( maybeProxy instanceof HibernateProxy ) {
final HibernateProxy proxy = (HibernateProxy) maybeProxy;
final LazyInitializer li = proxy.getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
throw new PersistentObjectException(
"object was an uninitialized proxy for " + li.getEntityName()
);
}
//unwrap the object and return
return li.getImplementation();
}
else {
return maybeProxy;
}
}
/**
* Check if the property is initialized. If the named property does not exist
* or is not persistent, this method always returns <tt>true</tt>.
*
* @param proxy The potential proxy
* @param propertyName the name of a persistent attribute of the object
* @return true if the named property of the object is not listed as uninitialized; false otherwise
*/
public static boolean isPropertyInitialized(Object proxy, String propertyName) {
final Object entity;
if ( proxy instanceof HibernateProxy ) {
final LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
return false;
}
else {
entity = li.getImplementation();
}
}
else {
entity = proxy;
}
if ( entity instanceof PersistentAttributeInterceptable ) {
PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
if ( interceptor != null && interceptor instanceof LazyAttributeLoadingInterceptor ) {
return ( (LazyAttributeLoadingInterceptor) interceptor ).isAttributeLoaded( propertyName );
}
}
return true;
}
@Override
public String bestGuessEntityName(Object object) {
if ( object instanceof HibernateProxy ) {
LazyInitializer initializer = ( (HibernateProxy) object ).getHibernateLazyInitializer();
// it is possible for this method to be called during flush processing,
// so make certain that we do not accidentally initialize an uninitialized proxy
if ( initializer.isUninitialized() ) {
return initializer.getEntityName();
}
object = initializer.getImplementation();
}
EntityEntry entry = persistenceContext.getEntry( object );
if ( entry == null ) {
return guessEntityName( object );
}
else {
return entry.getPersister().getEntityName();
}
}
public boolean contains(Object collection, Object childObject, SharedSessionContractImplementor session) {
// we do not have to worry about queued additions to uninitialized
// collections, since they can only occur for inverse collections!
Iterator elems = getElementsIterator( collection, session );
while ( elems.hasNext() ) {
Object element = elems.next();
// worrying about proxies is perhaps a little bit of overkill here...
if ( element instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) element ).getHibernateLazyInitializer();
if ( !li.isUninitialized() ) {
element = li.getImplementation();
}
}
if ( element == childObject ) {
return true;
}
}
return false;
}
/**
* Get the entity instance underlying the given proxy, throwing
* an exception if the proxy is uninitialized. If the given object
* is not a proxy, simply return the argument.
*/
public Object unproxy(Object maybeProxy) throws HibernateException {
if ( maybeProxy instanceof ElementWrapper ) {
maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
}
if ( maybeProxy instanceof HibernateProxy ) {
HibernateProxy proxy = (HibernateProxy) maybeProxy;
LazyInitializer li = proxy.getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
throw new PersistentObjectException(
"object was an uninitialized proxy for " +
li.getEntityName()
);
}
return li.getImplementation(); //unwrap the object
}
else {
return maybeProxy;
}
}
/**
* Check if the property is initialized. If the named property does not exist
* or is not persistent, this method always returns <tt>true</tt>.
*
* @param proxy The potential proxy
* @param propertyName the name of a persistent attribute of the object
* @return true if the named property of the object is not listed as uninitialized
* @return false if the object is an uninitialized proxy, or the named property is uninitialized
*/
public static boolean isPropertyInitialized(Object proxy, String propertyName) {
Object entity;
if ( proxy instanceof HibernateProxy ) {
LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
return false;
}
else {
entity = li.getImplementation();
}
}
else {
entity = proxy;
}
if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
return interceptor == null || interceptor.isInitialized( propertyName );
}
else {
return true;
}
}
public String bestGuessEntityName(Object object) {
if (object instanceof HibernateProxy) {
LazyInitializer initializer = ( ( HibernateProxy ) object ).getHibernateLazyInitializer();
// it is possible for this method to be called during flush processing,
// so make certain that we do not accidently initialize an uninitialized proxy
if ( initializer.isUninitialized() ) {
return initializer.getEntityName();
}
object = initializer.getImplementation();
}
EntityEntry entry = persistenceContext.getEntry(object);
if (entry==null) {
return guessEntityName(object);
}
else {
return entry.getPersister().getEntityName();
}
}
private EntityPersister guessEntityPersister(Object object) {
if ( scope == null ) {
return null;
}
String entityName = null;
// this code is largely copied from Session's bestGuessEntityName
Object entity = object;
if ( entity instanceof HibernateProxy ) {
final LazyInitializer initializer = ( (HibernateProxy) entity ).getHibernateLazyInitializer();
if ( initializer.isUninitialized() ) {
entityName = initializer.getEntityName();
}
entity = initializer.getImplementation();
}
if ( entityName == null ) {
for ( EntityNameResolver resolver : scope.getTypeConfiguration().getSessionFactory().getMetamodel().getEntityNameResolvers() ) {
entityName = resolver.resolveEntityName( entity );
if ( entityName != null ) {
break;
}
}
}
if ( entityName == null ) {
// the old-time stand-by...
entityName = object.getClass().getName();
}
return scope.getTypeConfiguration().getSessionFactory().getMetamodel().entityPersister( entityName );
}
public Object unwrapProxy(final HibernateProxy proxy) {
final LazyInitializer lazyInitializer = proxy.getHibernateLazyInitializer();
if (lazyInitializer.isUninitialized()) {
lazyInitializer.initialize();
}
final Object obj = lazyInitializer.getImplementation();
if (obj != null) {
ensureCorrectGroovyMetaClass(obj, obj.getClass());
}
return obj;
}
public void initialize(Object o) {
if (o instanceof HibernateProxy) {
final LazyInitializer hibernateLazyInitializer = ((HibernateProxy)o).getHibernateLazyInitializer();
if (hibernateLazyInitializer.isUninitialized()) {
hibernateLazyInitializer.initialize();
}
}
else {
super.initialize(o);
}
}
public boolean contains(Object object) {
errorIfClosed();
checkTransactionSynchStatus();
if ( object instanceof HibernateProxy ) {
//do not use proxiesByKey, since not all
//proxies that point to this session's
//instances are in that collection!
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
//if it is an uninitialized proxy, pointing
//with this session, then when it is accessed,
//the underlying instance will be "contained"
return li.getSession()==this;
}
else {
//if it is initialized, see if the underlying
//instance is contained, since we need to
//account for the fact that it might have been
//evicted
object = li.getImplementation();
}
}
// A session is considered to contain an entity only if the entity has
// an entry in the session's persistence context and the entry reports
// that the entity has not been removed
EntityEntry entry = persistenceContext.getEntry( object );
return entry != null && entry.getStatus() != Status.DELETED && entry.getStatus() != Status.GONE;
}
public boolean contains(Object collection, Object childObject, SessionImplementor session) {
// we do not have to worry about queued additions to uninitialized
// collections, since they can only occur for inverse collections!
Iterator elems = getElementsIterator( collection, session );
while ( elems.hasNext() ) {
Object element = elems.next();
// worrying about proxies is perhaps a little bit of overkill here...
if ( element instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) element ).getHibernateLazyInitializer();
if ( !li.isUninitialized() ) element = li.getImplementation();
}
if ( element == childObject ) return true;
}
return false;
}
/**
* extract the id from the proxy without initializing it
*/
public static Long getId(AbstractModel model) {
if (model instanceof HibernateProxy) {
LazyInitializer lazyInitializer = ((HibernateProxy) model).getHibernateLazyInitializer();
if (lazyInitializer.isUninitialized()) {
return (Long) lazyInitializer.getIdentifier();
}
}
return model.getId();
}
/**
* Handle the given create event.
*
* @param event The create event to be handled.
*/
public CompletionStage<Void> reactiveOnPersist(PersistEvent event, IdentitySet createCache) throws HibernateException {
final SessionImplementor source = event.getSession();
final Object object = event.getObject();
final Object entity;
if ( object instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
if ( li.getSession() == source ) {
return CompletionStages.nullFuture(); //NOTE EARLY EXIT!
}
else {
return CompletionStages.failedFuture( new PersistentObjectException( "uninitialized proxy passed to persist()" ) );
}
}
entity = li.getImplementation();
}
else {
entity = object;
}
final String entityName;
if ( event.getEntityName() != null ) {
entityName = event.getEntityName();
}
else {
entityName = source.bestGuessEntityName( entity );
event.setEntityName( entityName );
}
final EntityEntry entityEntry = source.getPersistenceContextInternal().getEntry( entity );
EntityState entityState = EntityState.getEntityState( entity, entityName, entityEntry, source, true );
if ( entityState == EntityState.DETACHED ) {
// JPA 2, in its version of a "foreign generated", allows the id attribute value
// to be manually set by the user, even though this manual value is irrelevant.
// The issue is that this causes problems with the Hibernate unsaved-value strategy
// which comes into play here in determining detached/transient state.
//
// Detect if we have this situation and if so null out the id value and calculate the
// entity state again.
// NOTE: entityEntry must be null to get here, so we cannot use any of its values
EntityPersister persister = source.getFactory().getMetamodel().entityPersister( entityName );
if (persister.getIdentifierGenerator() instanceof ForeignGenerator) {
if ( LOG.isDebugEnabled() && persister.getIdentifier( entity, source ) != null ) {
LOG.debug( "Resetting entity id attribute to null for foreign generator" );
}
persister.setIdentifier( entity, null, source );
entityState = EntityState.getEntityState( entity, entityName, entityEntry, source, true );
}
}
switch ( entityState ) {
case DETACHED: {
return CompletionStages.failedFuture( new PersistentObjectException(
"detached entity passed to persist: " +
EventUtil.getLoggableName( event.getEntityName(), entity )
) );
}
case PERSISTENT: {
return entityIsPersistent( event, createCache );
}
case TRANSIENT: {
return entityIsTransient( event, createCache );
}
case DELETED: {
entityEntry.setStatus( Status.MANAGED );
entityEntry.setDeletedState( null );
event.getSession().getActionQueue().unScheduleDeletion( entityEntry, event.getObject() );
return entityIsDeleted( event, createCache );
}
default: {
return CompletionStages.failedFuture( new ObjectDeletedException(
"deleted entity passed to persist",
null,
EventUtil.getLoggableName( event.getEntityName(), entity )
) );
}
}
}
/**
* Handle the given create event.
*
* @param event The create event to be handled.
*
*/
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
final SessionImplementor source = event.getSession();
final Object object = event.getObject();
final Object entity;
if ( object instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
if ( li.getSession() == source ) {
return; //NOTE EARLY EXIT!
}
else {
throw new PersistentObjectException( "uninitialized proxy passed to persist()" );
}
}
entity = li.getImplementation();
}
else {
entity = object;
}
final String entityName;
if ( event.getEntityName() != null ) {
entityName = event.getEntityName();
}
else {
entityName = source.bestGuessEntityName( entity );
event.setEntityName( entityName );
}
final EntityEntry entityEntry = source.getPersistenceContext().getEntry( entity );
EntityState entityState = getEntityState( entity, entityName, entityEntry, source );
if ( entityState == EntityState.DETACHED ) {
// JPA 2, in its version of a "foreign generated", allows the id attribute value
// to be manually set by the user, even though this manual value is irrelevant.
// The issue is that this causes problems with the Hibernate unsaved-value strategy
// which comes into play here in determining detached/transient state.
//
// Detect if we have this situation and if so null out the id value and calculate the
// entity state again.
// NOTE: entityEntry must be null to get here, so we cannot use any of its values
EntityPersister persister = source.getFactory().getEntityPersister( entityName );
if ( ForeignGenerator.class.isInstance( persister.getIdentifierGenerator() ) ) {
if ( LOG.isDebugEnabled() && persister.getIdentifier( entity, source ) != null ) {
LOG.debug( "Resetting entity id attribute to null for foreign generator" );
}
persister.setIdentifier( entity, null, source );
entityState = getEntityState( entity, entityName, entityEntry, source );
}
}
switch ( entityState ) {
case DETACHED: {
throw new PersistentObjectException(
"detached entity passed to persist: " +
getLoggableName( event.getEntityName(), entity )
);
}
case PERSISTENT: {
entityIsPersistent( event, createCache );
break;
}
case TRANSIENT: {
entityIsTransient( event, createCache );
break;
}
case DELETED: {
entityEntry.setStatus( Status.MANAGED );
entityEntry.setDeletedState( null );
event.getSession().getActionQueue().unScheduleDeletion( entityEntry, event.getObject() );
entityIsDeleted( event, createCache );
break;
}
default: {
throw new ObjectDeletedException(
"deleted entity passed to persist",
null,
getLoggableName( event.getEntityName(), entity )
);
}
}
}
/**
* Handle the given merge event.
*
* @param event The merge event to be handled.
*
* @throws HibernateException
*/
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException {
final MergeContext copyCache = (MergeContext) copiedAlready;
final EventSource source = event.getSession();
final Object original = event.getOriginal();
if ( original != null ) {
final Object entity;
if ( original instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
LOG.trace( "Ignoring uninitialized proxy" );
event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
return; //EARLY EXIT!
}
else {
entity = li.getImplementation();
}
}
else {
entity = original;
}
if ( copyCache.containsKey( entity ) &&
( copyCache.isOperatedOn( entity ) ) ) {
LOG.trace( "Already in merge process" );
event.setResult( entity );
}
else {
if ( copyCache.containsKey( entity ) ) {
LOG.trace( "Already in copyCache; setting in merge process" );
copyCache.setOperatedOn( entity, true );
}
event.setEntity( entity );
EntityState entityState = null;
// Check the persistence context for an entry relating to this
// entity to be merged...
EntityEntry entry = source.getPersistenceContext().getEntry( entity );
if ( entry == null ) {
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
Serializable id = persister.getIdentifier( entity, source );
if ( id != null ) {
final EntityKey key = source.generateEntityKey( id, persister );
final Object managedEntity = source.getPersistenceContext().getEntity( key );
entry = source.getPersistenceContext().getEntry( managedEntity );
if ( entry != null ) {
// we have specialized case of a detached entity from the
// perspective of the merge operation. Specifically, we
// have an incoming entity instance which has a corresponding
// entry in the current persistence context, but registered
// under a different entity instance
entityState = EntityState.DETACHED;
}
}
}
if ( entityState == null ) {
entityState = getEntityState( entity, event.getEntityName(), entry, source );
}
switch ( entityState ) {
case DETACHED:
entityIsDetached( event, copyCache );
break;
case TRANSIENT:
entityIsTransient( event, copyCache );
break;
case PERSISTENT:
entityIsPersistent( event, copyCache );
break;
default: //DELETED
throw new ObjectDeletedException(
"deleted instance passed to merge",
null,
getLoggableName( event.getEntityName(), entity )
);
}
}
}
}
/**
* Handle the given create event.
*
* @param event The create event to be handled.
* @throws HibernateException
*/
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
final SessionImplementor source = event.getSession();
final Object object = event.getObject();
final Object entity;
if (object instanceof HibernateProxy) {
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
if ( li.getSession()==source ) {
return; //NOTE EARLY EXIT!
}
else {
throw new PersistentObjectException("uninitialized proxy passed to persist()");
}
}
entity = li.getImplementation();
}
else {
entity = object;
}
int entityState = getEntityState(
entity,
event.getEntityName(),
source.getPersistenceContext().getEntry(entity),
source
);
switch (entityState) {
case DETACHED:
throw new PersistentObjectException(
"detached entity passed to persist: " +
getLoggableName( event.getEntityName(), entity )
);
case PERSISTENT:
entityIsPersistent(event, createCache);
break;
case TRANSIENT:
entityIsTransient(event, createCache);
break;
default:
throw new ObjectDeletedException(
"deleted entity passed to persist",
null,
getLoggableName( event.getEntityName(), entity )
);
}
}
/**
* Handle the given merge event.
*
* @param event The merge event to be handled.
* @throws HibernateException
*/
public void onMerge(MergeEvent event, Map copyCache) throws HibernateException {
final EventSource source = event.getSession();
final Object original = event.getOriginal();
if ( original != null ) {
final Object entity;
if ( original instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
log.trace("ignoring uninitialized proxy");
event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
return; //EARLY EXIT!
}
else {
entity = li.getImplementation();
}
}
else {
entity = original;
}
if ( copyCache.containsKey(entity) ) {
log.trace("already merged");
event.setResult(entity);
}
else {
event.setEntity( entity );
int entityState = -1;
// Check the persistence context for an entry relating to this
// entity to be merged...
EntityEntry entry = source.getPersistenceContext().getEntry( entity );
if ( entry == null ) {
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
if ( id != null ) {
EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
Object managedEntity = source.getPersistenceContext().getEntity( key );
entry = source.getPersistenceContext().getEntry( managedEntity );
if ( entry != null ) {
// we have specialized case of a detached entity from the
// perspective of the merge operation. Specifically, we
// have an incoming entity instance which has a corresponding
// entry in the current persistence context, but registered
// under a different entity instance
entityState = DETACHED;
}
}
}
if ( entityState == -1 ) {
entityState = getEntityState( entity, event.getEntityName(), entry, source );
}
switch (entityState) {
case DETACHED:
entityIsDetached(event, copyCache);
break;
case TRANSIENT:
entityIsTransient(event, copyCache);
break;
case PERSISTENT:
entityIsPersistent(event, copyCache);
break;
default: //DELETED
throw new ObjectDeletedException(
"deleted instance passed to merge",
null,
getLoggableName( event.getEntityName(), entity )
);
}
}
}
}