下面列出了org.hibernate.collection.PersistentList#org.hibernate.collection.PersistentCollection 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
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" );
}
}
}
private static void processNeverReferencedCollection(PersistentCollection coll, SessionImplementor session)
throws HibernateException {
final PersistenceContext persistenceContext = session.getPersistenceContext();
CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
log.debug(
"Found collection with unloaded owner: " +
MessageHelper.collectionInfoString(
entry.getLoadedPersister(),
entry.getLoadedKey(),
session.getFactory()
)
);
entry.setCurrentPersister( entry.getLoadedPersister() );
entry.setCurrentKey( entry.getLoadedKey() );
prepareCollectionForUpdate( coll, entry, session.getEntityMode(), session.getFactory() );
}
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() );
}
}
/**
* 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 );
}
}
}
/**
* Add an collection to the cache, with a given collection entry.
*
* @param coll The collection for which we are adding an entry.
* @param entry The entry representing the collection.
* @param key The key of the collection's entry.
*/
private void addCollection(PersistentCollection coll, CollectionEntry entry, Serializable key) {
collectionEntries.put( coll, entry );
CollectionKey collectionKey = new CollectionKey( entry.getLoadedPersister(), key, session.getEntityMode() );
PersistentCollection old = ( PersistentCollection ) collectionsByKey.put( collectionKey, coll );
if ( old != null ) {
if ( old == coll ) {
throw new AssertionFailure("bug adding collection twice");
}
// or should it actually throw an exception?
old.unsetSession( session );
collectionEntries.remove( old );
// watch out for a case where old is still referenced
// somewhere in the object graph! (which is a user error)
}
}
/**
* 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;
}
}
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() )
);
}
}
/**
* record the fact that this collection was dereferenced
*
* @param coll The collection to be updated by unreachability.
* @throws HibernateException
*/
public static void processUnreachableCollection(PersistentCollection coll, SessionImplementor session)
throws HibernateException {
if ( coll.getOwner()==null ) {
processNeverReferencedCollection(coll, session);
}
else {
processDereferencedCollection(coll, session);
}
}
public CollectionRecreateAction(
final PersistentCollection collection,
final CollectionPersister persister,
final Serializable id,
final SessionImplementor session)
throws CacheException {
super( persister, collection, id, session );
}
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 );
}
}
public PersistentCollection wrap(SessionImplementor session, Object collection) {
if ( session.getEntityMode()==EntityMode.DOM4J ) {
return new PersistentElementHolder( session, (Element) collection );
}
else {
return new PersistentBag( session, (Collection) collection );
}
}
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() );
if ( isUpdate ) {
removeCollection( persister, extractCollectionKeyFromOwner( persister ), session );
}
if ( collection != null && ( collection instanceof PersistentCollection ) ) {
PersistentCollection wrapper = ( PersistentCollection ) collection;
wrapper.setCurrentSession( session );
if ( wrapper.wasInitialized() ) {
session.getPersistenceContext().addNewCollection( persister, wrapper );
}
else {
reattachCollection( wrapper, type );
}
}
else {
// otherwise a null or brand new collection
// this will also (inefficiently) handle arrays, which
// have no snapshot, so we can't do any better
//processArrayOrNewCollection(collection, type);
}
return null;
}
public void initializeCollection(PersistentCollection collection, boolean writing)
throws HibernateException {
errorIfClosed();
checkTransactionSynchStatus();
InitializeCollectionEventListener[] listener = listeners.getInitializeCollectionEventListeners();
for ( int i = 0; i < listener.length; i++ ) {
listener[i].onInitializeCollection( new InitializeCollectionEvent(collection, this) );
}
}
/**
* For initialized detached collections
*/
CollectionEntry(PersistentCollection collection, SessionFactoryImplementor factory)
throws MappingException {
// detached collections that get found + reattached
// during flush shouldn't be ignored
ignore = false;
loadedKey = collection.getKey();
setLoadedPersister( factory.getCollectionPersister( collection.getRole() ) );
snapshot = collection.getStoredSnapshot();
}
/**
* 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();
}
}
/**
* 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();
}
/**
* Get the collection orphans (entities which were removed from the collection)
*/
public Collection getOrphans(String entityName, PersistentCollection collection)
throws HibernateException {
if (snapshot==null) {
throw new AssertionFailure("no collection snapshot for orphan delete");
}
return collection.getOrphans( snapshot, entityName );
}
public boolean isSnapshotEmpty(PersistentCollection collection) {
//TODO: does this really need to be here?
// does the collection already have
// it's own up-to-date snapshot?
return collection.wasInitialized() &&
( getLoadedPersister()==null || getLoadedPersister().isMutable() ) &&
collection.isSnapshotEmpty( getSnapshot() );
}
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 CollectionRemoveAction(
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;
}
/**
* 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;
}
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
if ( session.getEntityMode()==EntityMode.DOM4J ) {
return new PersistentElementHolder(session, persister, key);
}
else {
return new PersistentSet(session);
}
}
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
if ( session.getEntityMode()==EntityMode.DOM4J ) {
return new PersistentMapElementHolder(session, persister, key);
}
else {
return new PersistentMap(session);
}
}
/**
* 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() ) );
}
/**
* 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;
}
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);
}
}
public PersistentCollection instantiate(
SessionImplementor session,
CollectionPersister persister, Serializable key)
throws HibernateException {
return new PersistentIdentifierBag(session);
}