/** * Execute an SQL query and attempt to instantiate instances of the class mapped by the given * persister from each row of the <tt>ResultSet</tt>. If an object is supplied, will attempt to * initialize that object. If a collection is supplied, attempt to initialize that collection. */ private List doQueryAndInitializeNonLazyCollections(final SessionImplementor session, final QueryParameters queryParameters, final boolean returnProxies) throws HibernateException, SQLException { final PersistenceContext persistenceContext = session.getPersistenceContext(); persistenceContext.beforeLoad(); List result; try { result = doQuery( session, queryParameters, returnProxies ); } finally { persistenceContext.afterLoad(); } persistenceContext.initializeNonLazyCollections(); return result; }
/** * Given that there is a pre-existing proxy. * Initialize it if necessary; narrow if necessary. */ private Object returnNarrowedProxy( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext, final Object proxy ) { log.trace("entity proxy found in session cache"); LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer(); if ( li.isUnwrap() ) { return li.getImplementation(); } Object impl = null; if ( !options.isAllowProxyCreation() ) { impl = load( event, persister, keyToLoad, options ); if ( impl == null ) { event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier()); } } return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ); }
protected static boolean isCached( PersistenceContext context, Serializable collectionKey, CollectionPersister persister, EntityMode entityMode) { if ( persister.hasCache() ) { CacheKey cacheKey = new CacheKey( collectionKey, persister.getKeyType(), persister.getRole(), entityMode, context.getSession().getFactory() ); return persister.getCacheAccessStrategy().get( cacheKey, context.getSession().getTimestamp() ) != null; } return false; }
/** * Initialize Collection (detached or not) * @param collection collection to initialize * @param session Session to use for initialization */ public static void initializeCollection(Collection collection, Session session) { if (collection instanceof AbstractPersistentCollection) { AbstractPersistentCollection ps = (AbstractPersistentCollection) collection; log.debug("Initalizing PersistentCollection of role: " + ps.getRole()); if (!ps.wasInitialized()) { SessionImpl source = (SessionImpl) session; PersistenceContext context = source.getPersistenceContext(); CollectionPersister cp = source.getFactory().getCollectionPersister(ps.getRole()); if (context.getCollectionEntry(ps) == null) { // detached context.addUninitializedDetachedCollection(cp, ps); } ps.setCurrentSession(context.getSession()); Hibernate.initialize(collection); } } }
private CollectionInitializer getSubselectInitializer(Serializable key, SessionImplementor session) { if ( !isSubselectLoadable() ) { return null; } final PersistenceContext persistenceContext = session.getPersistenceContext(); SubselectFetch subselect = persistenceContext.getBatchFetchQueue() .getSubselect( new EntityKey( key, getOwnerEntityPersister(), session.getEntityMode() ) ); if (subselect == null) { return null; } else { // Take care of any entities that might have // been evicted! Iterator iter = subselect.getResult().iterator(); while ( iter.hasNext() ) { if ( !persistenceContext.containsEntity( (EntityKey) iter.next() ) ) { iter.remove(); } } // Run a subquery loader return createSubselectInitializer( subselect, session ); } }
final Object processArrayOrNewCollection(Object collection, CollectionType collectionType) throws HibernateException { final SessionImplementor session = getSession(); if (collection==null) { //do nothing return null; } else { CollectionPersister persister = session.getFactory().getCollectionPersister( collectionType.getRole() ); final PersistenceContext persistenceContext = session.getPersistenceContext(); //TODO: move into collection type, so we can use polymorphism! if ( collectionType.hasHolder( session.getEntityMode() ) ) { if (collection==CollectionType.UNFETCHED_COLLECTION) return null; PersistentCollection ah = persistenceContext.getCollectionHolder(collection); if (ah==null) { ah = collectionType.wrap(session, collection); persistenceContext.addNewCollection( persister, ah ); persistenceContext.addCollectionHolder(ah); } return null; } else { PersistentCollection persistentCollection = collectionType.wrap(session, collection); persistenceContext.addNewCollection( persister, persistentCollection ); if ( log.isTraceEnabled() ) log.trace( "Wrapped collection in role: " + collectionType.getRole() ); return persistentCollection; //Force a substitution! } } }
/** * Based on configured options, will either return a pre-existing proxy, * generate a new proxy, or perform an actual load. * * @return The result of the proxy/load operation. * @throws HibernateException */ protected Object proxyOrLoad( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options) throws HibernateException { if ( log.isTraceEnabled() ) { log.trace( "loading entity: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } if ( !persister.hasProxy() ) { // this class has no proxies (so do a shortcut) return load(event, persister, keyToLoad, options); } else { final PersistenceContext persistenceContext = event.getSession().getPersistenceContext(); // look for a proxy Object proxy = persistenceContext.getProxy(keyToLoad); if ( proxy != null ) { return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy ); } else { if ( options.isAllowProxyCreation() ) { return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext ); } else { // return a newly loaded object return load(event, persister, keyToLoad, options); } } } }
/** * Given that there is no pre-existing proxy. * Check if the entity is already loaded. If it is, return the entity, * otherwise create and return a proxy. */ private Object createProxyIfNecessary( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext ) { Object existing = persistenceContext.getEntity( keyToLoad ); if ( existing != null ) { // return existing object or initialized proxy (unless deleted) log.trace( "entity found in session cache" ); if ( options.isCheckDeleted() ) { EntityEntry entry = persistenceContext.getEntry( existing ); Status status = entry.getStatus(); if ( status == Status.DELETED || status == Status.GONE ) { return null; } } return existing; } else { log.trace( "creating new proxy for entity" ); // return new uninitialized proxy Object proxy = persister.createProxy( event.getEntityId(), event.getSession() ); persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad); persistenceContext.addProxy(keyToLoad, proxy); return proxy; } }
/** * 1. Recreate the collection key -> collection map * 2. rebuild the collection entries * 3. call Interceptor.postFlush() */ protected void postFlush(SessionImplementor session) throws HibernateException { log.trace( "post flush" ); final PersistenceContext persistenceContext = session.getPersistenceContext(); persistenceContext.getCollectionsByKey().clear(); persistenceContext.getBatchFetchQueue() .clearSubselects(); //the database has changed now, so the subselect results need to be invalidated Iterator iter = persistenceContext.getCollectionEntries().entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry me = (Map.Entry) iter.next(); CollectionEntry collectionEntry = (CollectionEntry) me.getValue(); PersistentCollection persistentCollection = (PersistentCollection) me.getKey(); collectionEntry.postFlush(persistentCollection); if ( collectionEntry.getLoadedPersister() == null ) { //if the collection is dereferenced, remove from the session cache //iter.remove(); //does not work, since the entrySet is not backed by the set persistenceContext.getCollectionEntries() .remove(persistentCollection); } else { //otherwise recreate the mapping between the collection and its key CollectionKey collectionKey = new CollectionKey( collectionEntry.getLoadedPersister(), collectionEntry.getLoadedKey(), session.getEntityMode() ); persistenceContext.getCollectionsByKey() .put(collectionKey, persistentCollection); } } session.getInterceptor().postFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) ); }
/** * instantiate a collection wrapper (called when loading an object) * * @param key The collection owner key * @param session The session from which the request is originating. * @param owner The collection owner * @return The collection */ public Object getCollection(Serializable key, SessionImplementor session, Object owner) { CollectionPersister persister = getPersister( session ); final PersistenceContext persistenceContext = session.getPersistenceContext(); final EntityMode entityMode = session.getEntityMode(); if (entityMode==EntityMode.DOM4J && !isEmbeddedInXML) { return UNFETCHED_COLLECTION; } // check if collection is currently being loaded PersistentCollection collection = persistenceContext.getLoadContexts().locateLoadingCollection( persister, key ); if ( collection == null ) { // check if it is already completely loaded, but unowned collection = persistenceContext.useUnownedCollection( new CollectionKey(persister, key, entityMode) ); if ( collection == null ) { // create a new collection wrapper, to be initialized later collection = instantiate( session, persister, key ); collection.setOwner( owner ); persistenceContext.addUninitializedCollection( persister, collection, key ); // some collections are not lazy: if ( initializeImmediately( entityMode ) ) { session.initializeCollection( collection, false ); } else if ( !persister.isLazy() ) { persistenceContext.addNonLazyCollection( collection ); } if ( hasHolder( entityMode ) ) { session.getPersistenceContext().addCollectionHolder( collection ); } } } collection.setOwner( owner ); return collection.getValue(); }
/** * Load an instance by a unique key that is not the primary key. * * @param entityName The name of the entity to load * @param uniqueKeyPropertyName The name of the property defining the uniqie key. * @param key The unique key property value. * @param session The originating session. * @return The loaded entity * @throws HibernateException generally indicates problems performing the load. */ public Object loadByUniqueKey( String entityName, String uniqueKeyPropertyName, Object key, SessionImplementor session) throws HibernateException { final SessionFactoryImplementor factory = session.getFactory(); UniqueKeyLoadable persister = ( UniqueKeyLoadable ) factory.getEntityPersister( entityName ); //TODO: implement caching?! proxies?! EntityUniqueKey euk = new EntityUniqueKey( entityName, uniqueKeyPropertyName, key, getIdentifierOrUniqueKeyType( factory ), session.getEntityMode(), session.getFactory() ); final PersistenceContext persistenceContext = session.getPersistenceContext(); Object result = persistenceContext.getEntity( euk ); if ( result == null ) { result = persister.loadByUniqueKey( uniqueKeyPropertyName, key, session ); } return result == null ? null : persistenceContext.proxyFor( result ); }
/** * For missing objects associated by one-to-one with another object in the * result set, register the fact that the the object is missing with the * session. */ private void registerNonExists( final EntityKey[] keys, final Loadable[] persisters, final SessionImplementor session) { final int[] owners = getOwners(); if ( owners != null ) { EntityType[] ownerAssociationTypes = getOwnerAssociationTypes(); for ( int i = 0; i < keys.length; i++ ) { int owner = owners[i]; if ( owner > -1 ) { EntityKey ownerKey = keys[owner]; if ( keys[i] == null && ownerKey != null ) { final PersistenceContext persistenceContext = session.getPersistenceContext(); /*final boolean isPrimaryKey; final boolean isSpecialOneToOne; if ( ownerAssociationTypes == null || ownerAssociationTypes[i] == null ) { isPrimaryKey = true; isSpecialOneToOne = false; } else { isPrimaryKey = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName()==null; isSpecialOneToOne = ownerAssociationTypes[i].getLHSPropertyName()!=null; }*/ //TODO: can we *always* use the "null property" approach for everything? /*if ( isPrimaryKey && !isSpecialOneToOne ) { persistenceContext.addNonExistantEntityKey( new EntityKey( ownerKey.getIdentifier(), persisters[i], session.getEntityMode() ) ); } else if ( isSpecialOneToOne ) {*/ boolean isOneToOneAssociation = ownerAssociationTypes!=null && ownerAssociationTypes[i]!=null && ownerAssociationTypes[i].isOneToOne(); if ( isOneToOneAssociation ) { persistenceContext.addNullProperty( ownerKey, ownerAssociationTypes[i].getPropertyName() ); } /*} else { persistenceContext.addNonExistantEntityUniqueKey( new EntityUniqueKey( persisters[i].getEntityName(), ownerAssociationTypes[i].getRHSUniqueKeyPropertyName(), ownerKey.getIdentifier(), persisters[owner].getIdentifierType(), session.getEntityMode() ) ); }*/ } } } } }
/** * Read one collection element from the current row of the JDBC result set */ private void readCollectionElement( final Object optionalOwner, final Serializable optionalKey, final CollectionPersister persister, final CollectionAliases descriptor, final ResultSet rs, final SessionImplementor session) throws HibernateException, SQLException { final PersistenceContext persistenceContext = session.getPersistenceContext(); final Serializable collectionRowKey = (Serializable) persister.readKey( rs, descriptor.getSuffixedKeyAliases(), session ); if ( collectionRowKey != null ) { // we found a collection element in the result set if ( log.isDebugEnabled() ) { log.debug( "found row of collection: " + MessageHelper.collectionInfoString( persister, collectionRowKey, getFactory() ) ); } Object owner = optionalOwner; if ( owner == null ) { owner = persistenceContext.getCollectionOwner( collectionRowKey, persister ); if ( owner == null ) { //TODO: This is assertion is disabled because there is a bug that means the // original owner of a transient, uninitialized collection is not known // if the collection is re-referenced by a different object associated // with the current Session //throw new AssertionFailure("bug loading unowned collection"); } } PersistentCollection rowCollection = persistenceContext.getLoadContexts() .getCollectionLoadContext( rs ) .getLoadingCollection( persister, collectionRowKey ); if ( rowCollection != null ) { rowCollection.readFrom( rs, persister, descriptor, owner ); } } else if ( optionalKey != null ) { // we did not find a collection element in the result set, so we // ensure that a collection is created with the owner's identifier, // since what we have is an empty collection if ( log.isDebugEnabled() ) { log.debug( "result set contains (possibly empty) collection: " + MessageHelper.collectionInfoString( persister, optionalKey, getFactory() ) ); } persistenceContext.getLoadContexts() .getCollectionLoadContext( rs ) .getLoadingCollection( persister, optionalKey ); // handle empty collection } // else no collection element, but also no owner }
/** * Perform the entity deletion. Well, as with most operations, does not * really perform it; just schedules an action/execution with the * {@link org.hibernate.engine.ActionQueue} for execution during flush. * * @param session The originating session * @param entity The entity to delete * @param entityEntry The entity's entry in the {@link PersistenceContext} * @param isCascadeDeleteEnabled Is delete cascading enabled? * @param persister The entity persister. * @param transientEntities A cache of already deleted entities. */ protected final void deleteEntity( final EventSource session, final Object entity, final EntityEntry entityEntry, final boolean isCascadeDeleteEnabled, final EntityPersister persister, final Set transientEntities) { if ( log.isTraceEnabled() ) { log.trace( "deleting " + MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() ) ); } final PersistenceContext persistenceContext = session.getPersistenceContext(); final Type[] propTypes = persister.getPropertyTypes(); final Object version = entityEntry.getVersion(); final Object[] currentState; if ( entityEntry.getLoadedState() == null ) { //ie. the entity came in from update() currentState = persister.getPropertyValues( entity, session.getEntityMode() ); } else { currentState = entityEntry.getLoadedState(); } final Object[] deletedState = createDeletedState( persister, currentState, session ); entityEntry.setDeletedState( deletedState ); session.getInterceptor().onDelete( entity, entityEntry.getId(), deletedState, persister.getPropertyNames(), propTypes ); // before any callbacks, etc, so subdeletions see that this deletion happened first persistenceContext.setEntryStatus( entityEntry, Status.DELETED ); EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode() ); cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities ); new ForeignKeys.Nullifier( entity, true, false, session ) .nullifyTransientReferences( entityEntry.getDeletedState(), propTypes ); new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, true ); persistenceContext.getNullifiableEntityKeys().add( key ); // Ensures that containing deletions happen before sub-deletions session.getActionQueue().addAction( new EntityDeleteAction( entityEntry.getId(), deletedState, version, entity, persister, isCascadeDeleteEnabled, session ) ); cascadeAfterDelete( session, persister, entity, transientEntities ); // the entry will be removed after the flush, and will no longer // override the stale snapshot // This is now handled by removeEntity() in EntityDeleteAction //persistenceContext.removeDatabaseSnapshot(key); }
/** * Try to initialize a collection from the cache */ private boolean initializeCollectionFromCache( Serializable id, CollectionPersister persister, PersistentCollection collection, SessionImplementor source) throws HibernateException { if ( !source.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( source ) ) { log.trace( "disregarding cached version (if any) of collection due to enabled filters "); return false; } final boolean useCache = persister.hasCache() && source.getCacheMode().isGetEnabled(); if ( !useCache ) { return false; } else { final SessionFactoryImplementor factory = source.getFactory(); final CacheKey ck = new CacheKey( id, persister.getKeyType(), persister.getRole(), source.getEntityMode(), source.getFactory() ); Object ce = persister.getCache().get( ck, source.getTimestamp() ); if ( factory.getStatistics().isStatisticsEnabled() ) { if (ce==null) { factory.getStatisticsImplementor().secondLevelCacheMiss( persister.getCache().getRegionName() ); } else { factory.getStatisticsImplementor().secondLevelCacheHit( persister.getCache().getRegionName() ); } } if (ce==null) { return false; } else { CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure() .destructure(ce, factory); final PersistenceContext persistenceContext = source.getPersistenceContext(); cacheEntry.assemble( collection, persister, persistenceContext.getCollectionOwner(id, persister) ); persistenceContext.getCollectionEntry(collection).postInitialize(collection); //addInitializedCollection(collection, persister, id); return true; } } }
private Object assembleCacheEntry( final CacheEntry entry, final Serializable id, final EntityPersister persister, final LoadEvent event) throws HibernateException { final Object optionalObject = event.getInstanceToLoad(); final EventSource session = event.getSession(); final SessionFactoryImplementor factory = session.getFactory(); if ( log.isTraceEnabled() ) { log.trace( "assembling entity from second-level cache: " + MessageHelper.infoString( persister, id, factory ) ); } EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() ); Object result = optionalObject == null ? session.instantiate( subclassPersister, id ) : optionalObject; // make it circular-reference safe TwoPhaseLoad.addUninitializedCachedEntity( new EntityKey( id, subclassPersister, session.getEntityMode() ), result, subclassPersister, LockMode.NONE, entry.areLazyPropertiesUnfetched(), entry.getVersion(), session ); Type[] types = subclassPersister.getPropertyTypes(); Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect TypeFactory.deepCopy( values, types, subclassPersister.getPropertyUpdateability(), values, session ); Object version = Versioning.getVersion( values, subclassPersister ); if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version ); final PersistenceContext persistenceContext = session.getPersistenceContext(); persistenceContext.addEntry( result, Status.MANAGED, values, null, id, version, LockMode.NONE, true, subclassPersister, false, entry.areLazyPropertiesUnfetched() ); subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session ); persistenceContext.initializeNonLazyCollections(); // upgrade the lock if necessary: //lock(result, lockMode); //PostLoad is needed for EJB3 //TODO: reuse the PostLoadEvent... PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result) .setId(id).setPersister(persister); PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners(); for ( int i = 0; i < listeners.length; i++ ) { listeners[i].onPostLoad(postLoadEvent); } return result; }
/** * Coordinates the processing necessary to get things ready for executions * as db calls by preping the session caches and moving the appropriate * entities and collections to their respective execution queues. * * @param event The flush event. * @throws HibernateException Error flushing caches to execution queues. */ protected void flushEverythingToExecutions(FlushEvent event) throws HibernateException { log.trace("flushing session"); EventSource session = event.getSession(); final PersistenceContext persistenceContext = session.getPersistenceContext(); session.getInterceptor().preFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) ); prepareEntityFlushes(session); // we could move this inside if we wanted to // tolerate collection initializations during // collection dirty checking: prepareCollectionFlushes(session); // now, any collections that are initialized // inside this block do not get updated - they // are ignored until the next flush persistenceContext.setFlushing(true); try { flushEntities(event); flushCollections(session); } finally { persistenceContext.setFlushing(false); } //some statistics if ( log.isDebugEnabled() ) { log.debug( "Flushed: " + session.getActionQueue().numberOfInsertions() + " insertions, " + session.getActionQueue().numberOfUpdates() + " updates, " + session.getActionQueue().numberOfDeletions() + " deletions to " + persistenceContext.getEntityEntries().size() + " objects" ); log.debug( "Flushed: " + session.getActionQueue().numberOfCollectionCreations() + " (re)creations, " + session.getActionQueue().numberOfCollectionUpdates() + " updates, " + session.getActionQueue().numberOfCollectionRemovals() + " removals to " + persistenceContext.getCollectionEntries().size() + " collections" ); new Printer( session.getFactory() ).toString( persistenceContext.getEntitiesByKey().values().iterator(), session.getEntityMode() ); } }
public PersistenceContext getPersistenceContext() { errorIfClosed(); checkTransactionSynchStatus(); return persistenceContext; }
public PersistenceContext getPersistenceContext() { return temporaryPersistenceContext; }
/** * Another problem with * http://build.e-monocot.org/bugzilla/show_bug.cgi?id=262 Unexpected Taxon * Exception in DwC Harvesting even though the taxon is expected. Comparing * HibernateProxies with non-proxies means you can't use o1.getClass() == * o2.getClass(). * @throws Exception if there is a problem */ @Test public final void testEqualsWithHibernateProxies() throws Exception { b2.setIdentifier("test"); b2.setId(1L); b1.setIdentifier("test"); b1.setId(1L); SessionImplementor sessionImplementor = EasyMock .createMock(SessionImplementor.class); SessionFactoryImplementor sessionFactoryImplementor = EasyMock .createMock(SessionFactoryImplementor.class); EntityPersister entityPersister = EasyMock .createMock(EntityPersister.class); PersistenceContext persistenceContext = EasyMock .createMock(PersistenceContext.class); EasyMock.expect(sessionImplementor.getFactory()) .andReturn(sessionFactoryImplementor).anyTimes(); EasyMock.expect( sessionFactoryImplementor.getEntityPersister((String) EasyMock .eq("Annotation"))).andReturn(entityPersister) .anyTimes(); EasyMock.expect(sessionImplementor.getPersistenceContext()).andReturn( persistenceContext); EasyMock.expect(persistenceContext.isDefaultReadOnly()) .andReturn(Boolean.TRUE).anyTimes(); EasyMock.expect(entityPersister.isMutable()).andReturn(Boolean.TRUE) .anyTimes(); EasyMock.expect(sessionImplementor.isClosed()).andReturn(Boolean.FALSE) .anyTimes(); EasyMock.expect(sessionImplementor.isOpen()).andReturn(Boolean.TRUE) .anyTimes(); EasyMock.expect(sessionImplementor.isConnected()) .andReturn(Boolean.TRUE).anyTimes(); EasyMock.expect( sessionImplementor.immediateLoad(EasyMock.eq("Annotation"), EasyMock.eq(1L))).andReturn(b2).anyTimes(); EasyMock.replay(sessionImplementor, sessionFactoryImplementor, entityPersister, persistenceContext); JavassistProxyFactory javassistProxyFactory = new JavassistProxyFactory(); Set interfaces = new HashSet(); interfaces.add(HibernateProxy.class); interfaces.add(Serializable.class); interfaces.add(Identifiable.class); interfaces.add(SecuredObject.class); javassistProxyFactory.postInstantiate("Annotation", Annotation.class, interfaces, Annotation.class.getDeclaredMethod("getId"), Annotation.class.getDeclaredMethod("setId", Long.class), null); b3 = javassistProxyFactory.getProxy(1L, sessionImplementor); EasyMock.verify(sessionImplementor, sessionFactoryImplementor, entityPersister, persistenceContext); assertTrue("Equals should return true", b1.equals(b3)); }
/** * Get a batch of uninitialized collection keys for a given role * Original implementation in org.hibernate.engine.BatchFetchQueue * This implementation maintains the sequence of the collection entries * * @param session The originating session * @param collectionPersister The persister for the collection role. * @param id A key that must be included in the batch fetch * @param batchSize the maximum number of keys to return * @return an array of collection keys, of length batchSize (padded with nulls) */ public static Serializable[] getCollectionBatch( final SessionImplementor session, final CollectionPersister collectionPersister, final Serializable id, final int batchSize, final EntityMode entityMode) { Serializable[] keys = new Serializable[batchSize]; keys[0] = id; int i = 1; //int count = 0; int end = -1; boolean checkForEnd = false; // this only works because collection entries are kept in a sequenced // map by persistence context (maybe we should do like entities and // keep a separate sequences set...) PersistenceContext context = session.getPersistenceContext(); Iterator iter = ((IdentityMap)context.getCollectionEntries()).entryList().iterator(); // Note the entryList() instead of the entrySet() while ( iter.hasNext() ) { Map.Entry me = (Map.Entry) iter.next(); CollectionEntry ce = (CollectionEntry) me.getValue(); PersistentCollection collection = (PersistentCollection) me.getKey(); if ( !collection.wasInitialized() && ce.getLoadedPersister() == collectionPersister ) { if ( checkForEnd && i == end ) { return keys; //the first key found after the given key } //if ( end == -1 && count > batchSize*10 ) return keys; //try out ten batches, max final boolean isEqual = collectionPersister.getKeyType().isEqual( id, ce.getLoadedKey(), entityMode, collectionPersister.getFactory() ); if ( isEqual ) { end = i; //checkForEnd = false; } else if ( !isCached( context, ce.getLoadedKey(), collectionPersister, entityMode ) ) { keys[i++] = ce.getLoadedKey(); //count++; } if ( i == batchSize ) { i = 1; //end of array, start filling again from start if ( end != -1 ) { checkForEnd = true; } } } } return keys; //we ran out of keys to try }
/** * Creates and binds this to the given persistence context. * * @param persistenceContext The persistence context to which this * will be bound. */ public LoadContexts(PersistenceContext persistenceContext) { this.persistenceContext = persistenceContext; }
/** * Retrieves the persistence context to which this is bound. * * @return The persistence context to which this is bound. */ public PersistenceContext getPersistenceContext() { return persistenceContext; }