1 package org.hibernate.engine; 3 4 import java.io.Serializable ; 5 import java.util.ArrayList ; 6 import java.util.Comparator ; 7 import java.util.HashMap ; 8 import java.util.Iterator ; 9 import java.util.List ; 10 import java.util.Map ; 11 12 import org.apache.commons.logging.Log; 13 import org.apache.commons.logging.LogFactory; 14 import org.hibernate.CacheMode; 15 import org.hibernate.EntityMode; 16 import org.hibernate.HibernateException; 17 import org.hibernate.cache.CacheKey; 18 import org.hibernate.cache.entry.CollectionCacheEntry; 19 import org.hibernate.collection.PersistentCollection; 20 import org.hibernate.persister.collection.CollectionPersister; 21 import org.hibernate.pretty.MessageHelper; 22 23 29 public class CollectionLoadContext { 30 31 private static final Log log = LogFactory.getLog(CollectionLoadContext.class); 32 33 private final Map loadingCollections = new HashMap (8); 35 private final PersistenceContext context; 36 37 public CollectionLoadContext(PersistenceContext context) { 38 this.context = context; 39 } 40 41 private static final class LoadingCollectionEntry { 42 43 final PersistentCollection collection; 44 final Serializable key; 45 final Object resultSetId; 46 final CollectionPersister persister; 47 48 LoadingCollectionEntry( 49 final PersistentCollection collection, 50 final Serializable key, 51 final CollectionPersister persister, 52 final Object resultSetId 53 ) { 54 this.collection = collection; 55 this.key = key; 56 this.persister = persister; 57 this.resultSetId = resultSetId; 58 } 59 } 60 61 66 public PersistentCollection getLoadingCollection( 67 final CollectionPersister persister, 68 final Serializable key, 69 final Object resultSetId, 70 final EntityMode em) 71 throws HibernateException { 72 CollectionKey ckey = new CollectionKey(persister, key, em); 73 LoadingCollectionEntry lce = getLoadingCollectionEntry(ckey); 74 if ( lce == null ) { 75 PersistentCollection collection = context.getCollection(ckey); 77 if ( collection != null ) { 78 if ( collection.wasInitialized() ) { 79 log.trace( "collection already initialized: ignoring" ); 80 return null; } 82 else { 83 log.trace( "uninitialized collection: initializing" ); 85 } 86 } 87 else { 88 Object entity = context.getCollectionOwner(key, persister); 89 final boolean newlySavedEntity = entity != null && 90 context.getEntry(entity).getStatus() != Status.LOADING && 91 em!=EntityMode.DOM4J; 92 if ( newlySavedEntity ) { 93 log.trace( "owning entity already loaded: ignoring" ); 96 return null; 97 } 98 else { 99 log.trace( "new collection: instantiating" ); 101 collection = persister.getCollectionType() 102 .instantiate( context.getSession(), persister, key ); 103 } 104 } 105 collection.beforeInitialize(persister); 106 collection.beginRead(); 107 addLoadingCollectionEntry(ckey, collection, persister, resultSetId); 108 return collection; 109 } 110 else { 111 if ( lce.resultSetId == resultSetId ) { 112 log.trace( "reading row" ); 113 return lce.collection; 114 } 115 else { 116 log.trace( "collection is already being initialized: ignoring row" ); 119 return null; 120 } 121 } 122 } 123 124 128 public PersistentCollection getLoadingCollection(CollectionPersister persister, Serializable id, EntityMode em) { 129 LoadingCollectionEntry lce = getLoadingCollectionEntry( new CollectionKey(persister, id, em) ); 130 if ( lce != null ) { 131 if ( log.isTraceEnabled() ) { 132 log.trace( 133 "returning loading collection:" + 134 MessageHelper.collectionInfoString(persister, id, context.getSession().getFactory()) 135 ); 136 } 137 return lce.collection; 138 } 139 else { 140 if ( log.isTraceEnabled() ) { 141 log.trace( 142 "creating collection wrapper:" + 143 MessageHelper.collectionInfoString(persister, id, context.getSession().getFactory()) 144 ); 145 } 146 return null; 147 } 148 } 149 150 153 private void addLoadingCollectionEntry( 154 final CollectionKey collectionKey, 155 final PersistentCollection collection, 156 final CollectionPersister persister, 157 final Object resultSetId 158 ) { 159 loadingCollections.put( 160 collectionKey, 161 new LoadingCollectionEntry( 162 collection, 163 collectionKey.getKey(), 164 persister, 165 resultSetId 166 ) 167 ); 168 } 169 170 173 private LoadingCollectionEntry getLoadingCollectionEntry(CollectionKey collectionKey) { 174 return ( LoadingCollectionEntry ) loadingCollections.get( collectionKey ); 175 } 176 177 181 private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister, EntityMode em) { 182 183 boolean hasNoQueuedAdds = lce.collection.endRead(); 185 if ( persister.getCollectionType().hasHolder(em) ) { 186 context.addCollectionHolder(lce.collection); 187 } 188 189 CollectionEntry ce = context.getCollectionEntry(lce.collection); 190 if ( ce==null ) { 191 ce = context.addInitializedCollection(persister, lce.collection, lce.key); 192 } 193 else { 194 ce.postInitialize(lce.collection); 195 } 196 197 final SessionImplementor session = context.getSession(); 198 199 boolean addToCache = hasNoQueuedAdds && persister.hasCache() && session.getCacheMode().isPutEnabled() && 202 !ce.isDoremove(); if (addToCache) addCollectionToCache(lce, persister); 204 205 if ( log.isDebugEnabled() ) { 206 log.debug( 207 "collection fully initialized: " + 208 MessageHelper.collectionInfoString(persister, lce.key, context.getSession().getFactory()) 209 ); 210 } 211 212 if ( session.getFactory().getStatistics().isStatisticsEnabled() ) { 213 session.getFactory().getStatisticsImplementor().loadCollection( 214 persister.getRole() 215 ); 216 } 217 218 } 219 222 public void endLoadingCollections(CollectionPersister persister, Object resultSetId, SessionImplementor session) 223 throws HibernateException { 224 225 List resultSetCollections = null; Iterator iter = loadingCollections.values().iterator(); 231 while ( iter.hasNext() ) { 232 LoadingCollectionEntry lce = (LoadingCollectionEntry) iter.next(); 233 if ( lce.resultSetId == resultSetId && lce.persister==persister) { 234 if ( resultSetCollections == null ) { 235 resultSetCollections = new ArrayList (); 236 } 237 resultSetCollections.add(lce); 238 if ( lce.collection.getOwner()==null ) { 239 session.getPersistenceContext() 240 .addUnownedCollection( 241 new CollectionKey( persister, lce.key, session.getEntityMode() ), 242 lce.collection 243 ); 244 } 245 iter.remove(); 246 } 247 } 248 249 endLoadingCollections( persister, resultSetCollections, session.getEntityMode() ); 250 } 251 252 256 private void endLoadingCollections(CollectionPersister persister, List resultSetCollections, EntityMode em) 257 throws HibernateException { 258 259 final int count = (resultSetCollections == null) ? 0 : resultSetCollections.size(); 260 261 if ( log.isDebugEnabled() ) { 262 log.debug( count + " collections were found in result set for role: " + persister.getRole() ); 263 } 264 265 for ( int i = 0; i < count; i++ ) { 267 LoadingCollectionEntry lce = (LoadingCollectionEntry) resultSetCollections.get(i); 268 endLoadingCollection(lce, persister, em); 269 } 270 271 if ( log.isDebugEnabled() ) { 272 log.debug( count + " collections initialized for role: " + persister.getRole() ); 273 } 274 } 275 276 279 private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersister persister) { 280 281 if ( log.isDebugEnabled() ) { 282 log.debug( 283 "Caching collection: " + 284 MessageHelper.collectionInfoString( persister, lce.key, context.getSession().getFactory() ) 285 ); 286 } 287 288 final SessionImplementor session = context.getSession(); 289 final SessionFactoryImplementor factory = session.getFactory(); 290 291 if ( !session.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( session ) ) { 292 log.debug( "Refusing to add to cache due to enabled filters" ); 294 return; } 301 302 final Comparator versionComparator; 303 final Object version; 304 if ( persister.isVersioned() ) { 305 versionComparator = persister.getOwnerEntityPersister().getVersionType().getComparator(); 306 version = context.getEntry( context.getCollectionOwner(lce.key, persister) ).getVersion(); 307 } 308 else { 309 version = null; 310 versionComparator = null; 311 } 312 313 CollectionCacheEntry entry = new CollectionCacheEntry(lce.collection, persister); 314 315 boolean put = persister.getCache().put( 316 new CacheKey( lce.key, persister.getKeyType(), persister.getRole(), session.getEntityMode(), session.getFactory() ), 317 persister.getCacheEntryStructure().structure(entry), 318 session.getTimestamp(), 319 version, 320 versionComparator, 321 factory.getSettings().isMinimalPutsEnabled() && session.getCacheMode()!=CacheMode.REFRESH 322 ); 323 324 if ( put && factory.getStatistics().isStatisticsEnabled() ) { 325 factory.getStatisticsImplementor().secondLevelCachePut( 326 persister.getCache().getRegionName() 327 ); 328 } 329 } 330 331 332 } 333 | Popular Tags |