public void updateRows(PersistentCollection collection, Serializable id, SessionImplementor session) throws HibernateException { if ( !isInverse && collection.isRowUpdatePossible() ) { if ( log.isDebugEnabled() ) { log.debug( "Updating rows of collection: " + role + "#" + id ); } //update all the modified entries int count = doUpdateRows( id, collection, session ); if ( log.isDebugEnabled() ) { log.debug( "done updating rows: " + count + " updated" ); } } }
@Override public void serialize(PersistentCollection coll, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { // If lazy-loaded, not yet loaded, may serialize as null? if (!_forceLazyLoading && !coll.wasInitialized()) { jgen.writeNull(); return; } Object value = coll.getValue(); if (value == null) { provider.defaultSerializeNull(jgen); } else { if (_serializer == null) { // sanity check... throw new JsonMappingException("PersitentCollection does not have serializer set"); } _serializer.serialize(value, jgen, provider); } }
/** * * @param o Set the object * @param association Set the association to initialize */ protected Object initializeProperty(final Object o, final String association) { Object object; try { object = PropertyUtils.getProperty(o, association); } catch (Exception e) { logger.debug("Cannot get proxy " + association + " for class " + o.getClass()); return null; } if (object == null) { return null; } else if (object instanceof HibernateProxy) { ((HibernateProxy) object).getHibernateLazyInitializer().initialize(); LazyInitializer lazyInitializer = ((HibernateProxy) object) .getHibernateLazyInitializer(); return lazyInitializer.getImplementation(); } else if (object instanceof PersistentCollection) { ((PersistentCollection) object).forceInitialization(); return object; } else { return object; } }
/** * Delete any entities that were removed from the collection */ private void deleteOrphans(String entityName, PersistentCollection pc) throws HibernateException { //TODO: suck this logic into the collection! final Collection orphans; if ( pc.wasInitialized() ) { CollectionEntry ce = eventSource.getPersistenceContext().getCollectionEntry(pc); orphans = ce==null ? CollectionHelper.EMPTY_COLLECTION : ce.getOrphans(entityName, pc); } else { orphans = pc.getQueuedOrphans(entityName); } final Iterator orphanIter = orphans.iterator(); while ( orphanIter.hasNext() ) { Object orphan = orphanIter.next(); if (orphan!=null) { if ( log.isTraceEnabled() ) { log.trace("deleting orphaned entity instance: " + entityName); } eventSource.delete( entityName, orphan, false, null ); } } }
/** * For collections just loaded from the database */ public CollectionEntry( final PersistentCollection collection, final CollectionPersister loadedPersister, final Serializable loadedKey, final boolean ignore ) { this.ignore=ignore; //collection.clearDirty() this.loadedKey = loadedKey; setLoadedPersister(loadedPersister); collection.setSnapshot(loadedKey, role, null); //postInitialize() will be called after initialization }
@Override public JsonSerializer<?> findSerializer( SerializationConfig config, JavaType type, BeanDescription beanDesc) { Class<?> raw = type.getRawClass(); /* Note: PersistentCollection does not implement Collection, so we * may get some types here... */ if (PersistentCollection.class.isAssignableFrom(raw)) { // TODO: handle iterator types? Or PersistentArrayHolder? } if (HibernateProxy.class.isAssignableFrom(raw)) { return new HibernateProxySerializer(isEnabled(Feature.FORCE_LAZY_LOADING)); } return null; }
/** * Force initialization of all non-lazy collections encountered during * the current two-phase load (actually, this is a no-op, unless this * is the "outermost" load) */ public void initializeNonLazyCollections() throws HibernateException { if ( loadCounter == 0 ) { log.debug( "initializing non-lazy collections" ); //do this work only at the very highest level of the load loadCounter++; //don't let this method be called recursively try { int size; while ( ( size = nonlazyCollections.size() ) > 0 ) { //note that each iteration of the loop may add new elements ( (PersistentCollection) nonlazyCollections.remove( size - 1 ) ).forceInitialization(); } } finally { loadCounter--; clearNullProperties(); } } }
/** * Attempt to locate the loading collection given the owner's key. The lookup here * occurs against all result-set contexts... * * @param persister The collection persister * @param ownerKey The owner key * @return The loading collection, or null if not found. */ public PersistentCollection locateLoadingCollection(CollectionPersister persister, Serializable ownerKey) { LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey, getEntityMode() ) ); if ( lce != null ) { if ( log.isTraceEnabled() ) { log.trace( "returning loading collection:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) ); } return lce.getCollection(); } else { // todo : should really move this log statement to CollectionType, where this is used from... if ( log.isTraceEnabled() ) { log.trace( "creating collection wrapper:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) ); } return null; } }
Object processCollection(Object collection, CollectionType collectionType) throws HibernateException { if ( collection!=null && (collection instanceof PersistentCollection) ) { final SessionImplementor session = getSession(); PersistentCollection coll = (PersistentCollection) collection; if ( coll.setCurrentSession(session) ) { reattachCollection( coll, collectionType ); } return null; } else { return processArrayOrNewCollection(collection, collectionType); } }
public void evictCollection(Object value, CollectionType type) { final Object pc; if ( type.hasHolder( getSession().getEntityMode() ) ) { pc = getSession().getPersistenceContext().removeCollectionHolder(value); } else if ( value instanceof PersistentCollection ) { pc = value; } else { return; //EARLY EXIT! } PersistentCollection collection = (PersistentCollection) pc; if ( collection.unsetSession( getSession() ) ) evictCollection(collection); }
public void execute() throws HibernateException { final PersistentCollection collection = getCollection(); getPersister().recreate( collection, getKey(), getSession() ); getSession().getPersistenceContext() .getCollectionEntry(collection) .afterAction(collection); evict(); if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor() .recreateCollection( getPersister().getRole() ); } }
public void execute() throws HibernateException { if ( !emptySnapshot ) getPersister().remove( getKey(), getSession() ); final PersistentCollection collection = getCollection(); if (collection!=null) { getSession().getPersistenceContext() .getCollectionEntry(collection) .afterAction(collection); } evict(); if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) { getSession().getFactory().getStatisticsImplementor() .removeCollection( getPersister().getRole() ); } }
/** * 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(); }
/** * Replace the elements of a collection with the elements of another collection. * * @param original The 'source' of the replacement elements (where we copy from) * @param target The target of the replacement elements (where we copy to) * @param owner The owner of the collection being merged * @param copyCache The map of elements already replaced. * @param session The session from which the merge event originated. * @return The merged collection. */ public Object replaceElements( Object original, Object target, Object owner, Map copyCache, SessionImplementor session) { // TODO: does not work for EntityMode.DOM4J yet! java.util.Collection result = ( java.util.Collection ) target; result.clear(); // copy elements into newly empty target collection Type elemType = getElementType( session.getFactory() ); Iterator iter = ( (java.util.Collection) original ).iterator(); while ( iter.hasNext() ) { result.add( elemType.replace( iter.next(), null, session, owner, copyCache ) ); } // if the original is a PersistentCollection, and that original // was not flagged as dirty, then reset the target's dirty flag // here after the copy operation. // </p> // One thing to be careful of here is a "bare" original collection // in which case we should never ever ever reset the dirty flag // on the target because we simply do not know... if ( original instanceof PersistentCollection ) { if ( result instanceof PersistentCollection ) { if ( ! ( ( PersistentCollection ) original ).isDirty() ) { ( ( PersistentCollection ) result ).clearDirty(); } } } return result; }
public PersistentCollection wrap(SessionImplementor session, Object collection) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentMapElementHolder( session, (Element) collection ); } else { return new PersistentMap( session, (java.util.Map) collection ); } }
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentListElementHolder(session, persister, key); } else { return new PersistentList(session); } }
/** * Determine if the collection is "really" dirty, by checking dirtiness * of the collection elements, if necessary */ private void dirty(PersistentCollection collection) throws HibernateException { boolean forceDirty = collection.wasInitialized() && !collection.isDirty() && //optimization getLoadedPersister() != null && getLoadedPersister().isMutable() && //optimization ( collection.isDirectlyAccessible() || getLoadedPersister().getElementType().isMutable() ) && //optimization !collection.equalsSnapshot( getLoadedPersister() ); if ( forceDirty ) { collection.dirty(); } }
public void preFlush(PersistentCollection collection) throws HibernateException { boolean nonMutableChange = collection.isDirty() && getLoadedPersister()!=null && !getLoadedPersister().isMutable(); if (nonMutableChange) { throw new HibernateException( "changed an immutable collection instance: " + MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() ) ); } dirty(collection); if ( log.isDebugEnabled() && collection.isDirty() && getLoadedPersister() != null ) { log.debug( "Collection dirty: " + MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() ) ); } setDoupdate(false); setDoremove(false); setDorecreate(false); setReached(false); setProcessed(false); }
/** * Called after execution of an action */ public void afterAction(PersistentCollection collection) { loadedKey = getCurrentKey(); setLoadedPersister( getCurrentPersister() ); boolean resnapshot = collection.wasInitialized() && ( isDoremove() || isDorecreate() || isDoupdate() ); if ( resnapshot ) { snapshot = loadedPersister==null || !loadedPersister.isMutable() ? null : collection.getSnapshot(loadedPersister); //re-snapshot } collection.postAction(); }
public PersistentCollection useUnownedCollection(CollectionKey key) { if (unownedCollections==null) { return null; } else { return (PersistentCollection) unownedCollections.remove(key); } }
public void clear() { Iterator itr = proxiesByKey.values().iterator(); while ( itr.hasNext() ) { final LazyInitializer li = ( ( HibernateProxy ) itr.next() ).getHibernateLazyInitializer(); li.setSession( null ); } Map.Entry[] collectionEntryArray = IdentityMap.concurrentEntries( collectionEntries ); for ( int i = 0; i < collectionEntryArray.length; i++ ) { ( ( PersistentCollection ) collectionEntryArray[i].getKey() ).unsetSession( getSession() ); } arrayHolders.clear(); entitiesByKey.clear(); entitiesByUniqueKey.clear(); entityEntries.clear(); entitySnapshotsByKey.clear(); collectionsByKey.clear(); collectionEntries.clear(); if ( unownedCollections != null ) { unownedCollections.clear(); } proxiesByKey.clear(); nullifiableEntityKeys.clear(); if ( batchFetchQueue != null ) { batchFetchQueue.clear(); } hasNonReadOnlyEntities = false; if ( loadContexts != null ) { loadContexts.cleanup(); } }
public PersistentCollection wrap(SessionImplementor session, Object collection) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentElementHolder( session, (Element) collection ); } else { return new PersistentSortedMap( session, (java.util.SortedMap) collection ); } }
/** * add an (initialized) collection that was created by another session and passed * into update() (ie. one with a snapshot and existing state on the database) */ public void addInitializedDetachedCollection(CollectionPersister collectionPersister, PersistentCollection collection) throws HibernateException { if ( collection.isUnreferenced() ) { //treat it just like a new collection addCollection( collection, collectionPersister ); } else { CollectionEntry ce = new CollectionEntry( collection, session.getFactory() ); addCollection( collection, ce, collection.getKey() ); } }
/** * add a collection we just pulled out of the cache (does not need initializing) */ public CollectionEntry addInitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id) throws HibernateException { CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing); ce.postInitialize(collection); addCollection(collection, ce, id); return ce; }
/** * Iterate just the elements of the collection that are already there. Don't load * any new elements from the database. */ public static Iterator getLoadedElementsIterator(SessionImplementor session, CollectionType collectionType, Object collection) { if ( collectionIsInitialized(collection) ) { // handles arrays and newly instantiated collections return collectionType.getElementsIterator(collection, session); } else { // does not handle arrays (thats ok, cos they can't be lazy) // or newly instantiated collections, so we can do the cast return ( (PersistentCollection) collection ).queuedAdditionIterator(); } }
public LoadingCollectionEntry( ResultSet resultSet, CollectionPersister persister, Serializable key, PersistentCollection collection) { this.resultSet = resultSet; this.persister = persister; this.key = key; this.collection = collection; }
/** * Force initialization of a proxy or persistent collection. * <p/> * Note: This only ensures intialization of a proxy object or collection; * it is not guaranteed that the elements INSIDE the collection will be initialized/materialized. * * @param proxy a persistable object, proxy, persistent collection or <tt>null</tt> * @throws HibernateException if we can't initialize the proxy at this time, eg. the <tt>Session</tt> was closed */ public static void initialize(Object proxy) throws HibernateException { if ( proxy == null ) { return; } else if ( proxy instanceof HibernateProxy ) { ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().initialize(); } else if ( proxy instanceof PersistentCollection ) { ( ( PersistentCollection ) proxy ).forceInitialization(); } }
/** * Check if the proxy or persistent collection is initialized. * * @param proxy a persistable object, proxy, persistent collection or <tt>null</tt> * @return true if the argument is already initialized, or is not a proxy or collection */ public static boolean isInitialized(Object proxy) { if ( proxy instanceof HibernateProxy ) { return !( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().isUninitialized(); } else if ( proxy instanceof PersistentCollection ) { return ( ( PersistentCollection ) proxy ).wasInitialized(); } else { return true; } }
public PersistentCollection wrap(SessionImplementor session, Object collection) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentElementHolder( session, (Element) collection ); } else { return new PersistentSortedSet( session, (java.util.SortedSet) collection ); } }
/** * {@inheritDoc} */ Object processCollection(Object collection, CollectionType type) throws HibernateException { if ( collection == CollectionType.UNFETCHED_COLLECTION ) { return null; } EventSource session = getSession(); CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() ); final Serializable collectionKey = extractCollectionKeyFromOwner( persister ); if ( collection!=null && (collection instanceof PersistentCollection) ) { PersistentCollection wrapper = (PersistentCollection) collection; if ( wrapper.setCurrentSession(session) ) { //a "detached" collection! if ( !isOwnerUnchanged( wrapper, persister, collectionKey ) ) { // if the collection belonged to a different entity, // clean up the existing state of the collection removeCollection( persister, collectionKey, session ); } reattachCollection(wrapper, type); } else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() removeCollection(persister, collectionKey, session); } } else { // null or brand new collection // this will also (inefficiently) handle arrays, which have // no snapshot, so we can't do any better removeCollection(persister, collectionKey, session); } return null; }
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! } } }
Object processCollection(Object collection, CollectionType type) throws HibernateException { SessionImplementor session = getSession(); CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() ); if ( collection == null ) { //do nothing } else if ( collection instanceof PersistentCollection ) { PersistentCollection persistentCollection = ( PersistentCollection ) collection; if ( persistentCollection.setCurrentSession( session ) ) { if ( isOwnerUnchanged( persistentCollection, persister, extractCollectionKeyFromOwner( persister ) ) ) { // a "detached" collection that originally belonged to the same entity if ( persistentCollection.isDirty() ) { throw new HibernateException( "reassociated object has dirty collection" ); } reattachCollection( persistentCollection, type ); } else { // a "detached" collection that belonged to a different entity throw new HibernateException( "reassociated object has dirty collection reference" ); } } else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() throw new HibernateException( "reassociated object has dirty collection reference" ); } } else { // brand new collection //TODO: or an array!! we can't lock objects with arrays now?? throw new HibernateException( "reassociated object has dirty collection reference (or an array)" ); } return null; }
/** * Has the owner of the collection changed since the collection * was snapshotted and detached? */ protected static boolean isOwnerUnchanged( final PersistentCollection snapshot, final CollectionPersister persister, final Serializable id ) { return isCollectionSnapshotValid(snapshot) && persister.getRole().equals( snapshot.getRole() ) && id.equals( snapshot.getKey() ); }
private void evictCollection(PersistentCollection collection) { CollectionEntry ce = (CollectionEntry) getSession().getPersistenceContext().getCollectionEntries().remove(collection); if ( log.isDebugEnabled() ) log.debug( "evicting collection: " + MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), getSession().getFactory() ) ); if ( ce.getLoadedPersister() != null && ce.getLoadedKey() != null ) { //TODO: is this 100% correct? getSession().getPersistenceContext().getCollectionsByKey().remove( new CollectionKey( ce.getLoadedPersister(), ce.getLoadedKey(), getSession().getEntityMode() ) ); } }
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentElementHolder(session, persister, key); } else { PersistentSortedSet set = new PersistentSortedSet(session); set.setComparator(comparator); return set; } }
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { if ( session.getEntityMode()==EntityMode.DOM4J ) { return new PersistentMapElementHolder(session, persister, key); } else { PersistentSortedMap map = new PersistentSortedMap(session); map.setComparator(comparator); return map; } }
public CollectionRecreateAction( final PersistentCollection collection, final CollectionPersister persister, final Serializable id, final SessionImplementor session) throws CacheException { super( persister, collection, id, session ); }
public CollectionAction( final CollectionPersister persister, final PersistentCollection collection, final Serializable key, final SessionImplementor session) throws CacheException { this.persister = persister; this.session = session; this.key = key; this.collectionRole = persister.getRole(); this.collection = collection; }
public CollectionUpdateAction( final PersistentCollection collection, final CollectionPersister persister, final Serializable id, final boolean emptySnapshot, final SessionImplementor session) throws CacheException { super( persister, collection, id, session ); this.emptySnapshot = emptySnapshot; }
@Override public PersistentCollection wrap(SessionImplementor session, Object collection) { if ( session.getEntityMode() == org.hibernate.EntityMode.DOM4J ) { throw new IllegalStateException("dom4j not supported"); } else { return new utils.PersistentOwnedSet( session, (java.util.Set) collection ); } }