We need an entry to tell us all about the current state
of a collection with respect to its persistent state
| Constructor: |
public CollectionEntry(CollectionPersister persister,
PersistentCollection collection) {
// new collections that get found + wrapped
// during flush shouldn't be ignored
ignore = false;
collection.clearDirty(); //a newly wrapped collection is NOT dirty (or we get unnecessary version updates)
snapshot = persister.isMutable() ?
collection.getSnapshot(persister) :
null;
collection.setSnapshot(loadedKey, role, snapshot);
}
For newly wrapped collections, or dereferenced collection wrappers |
public CollectionEntry(CollectionPersister loadedPersister,
Serializable loadedKey) {
// detached collection wrappers that get found + reattached
// during flush shouldn't be ignored
ignore = false;
//collection.clearDirty()
this.loadedKey = loadedKey;
setLoadedPersister(loadedPersister);
}
For uninitialized 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();
}
For initialized detached collections |
public CollectionEntry(PersistentCollection collection,
CollectionPersister loadedPersister,
Serializable loadedKey,
boolean ignore) {
this.ignore=ignore;
//collection.clearDirty()
this.loadedKey = loadedKey;
setLoadedPersister(loadedPersister);
collection.setSnapshot(loadedKey, role, null);
//postInitialize() will be called after initialization
}
For collections just loaded from the database |
| Method from org.hibernate.engine.CollectionEntry Detail: |
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();
}
Called after execution of an action |
void afterDeserialize(SessionFactoryImplementor factory) {
loadedPersister = factory.getCollectionPersister(role);
}
|
static CollectionEntry deserialize(ObjectInputStream ois,
SessionImplementor session) throws ClassNotFoundException, IOException {
return new CollectionEntry(
( String ) ois.readObject(),
( Serializable ) ois.readObject(),
( Serializable ) ois.readObject(),
session.getFactory()
);
}
Custom deserialization routine used during deserialization of a
Session/PersistenceContext for increased performance. |
public Serializable getCurrentKey() {
return currentKey;
}
This is only available late during the flush
cycle |
public CollectionPersister getCurrentPersister() {
return currentPersister;
}
|
public Serializable getKey() {
return getLoadedKey();
}
|
public Serializable getLoadedKey() {
return loadedKey;
}
|
public CollectionPersister getLoadedPersister() {
return loadedPersister;
}
This is only available late during the flush cycle |
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 );
}
Get the collection orphans (entities which were removed from the collection) |
public String getRole() {
return role;
}
|
public Serializable getSnapshot() {
return snapshot;
}
|
public boolean isDorecreate() {
return dorecreate;
}
|
public boolean isDoremove() {
return doremove;
}
|
public boolean isDoupdate() {
return doupdate;
}
|
public boolean isIgnore() {
return ignore;
}
|
public boolean isProcessed() {
return processed;
}
|
public boolean isReached() {
return reached;
}
|
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 postFlush(PersistentCollection collection) throws HibernateException {
if ( isIgnore() ) {
ignore = false;
}
else if ( !isProcessed() ) {
throw new AssertionFailure( "collection [" + collection.getRole() + "] was not processed by flush()" );
}
collection.setSnapshot(loadedKey, role, snapshot);
}
Called after a successful flush |
public void postInitialize(PersistentCollection collection) throws HibernateException {
snapshot = getLoadedPersister().isMutable() ?
collection.getSnapshot( getLoadedPersister() ) :
null;
collection.setSnapshot(loadedKey, role, snapshot);
}
|
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);
}
|
void serialize(ObjectOutputStream oos) throws IOException {
oos.writeObject( role );
oos.writeObject( snapshot );
oos.writeObject( loadedKey );
}
Custom serialization routine used during serialization of a
Session/PersistenceContext for increased performance. |
public void setCurrentKey(Serializable currentKey) {
this.currentKey = currentKey;
}
|
public void setCurrentPersister(CollectionPersister currentPersister) {
this.currentPersister = currentPersister;
}
|
public void setDorecreate(boolean dorecreate) {
this.dorecreate = dorecreate;
}
|
public void setDoremove(boolean doremove) {
this.doremove = doremove;
}
|
public void setDoupdate(boolean doupdate) {
this.doupdate = doupdate;
}
|
public void setProcessed(boolean processed) {
this.processed = processed;
}
|
public void setReached(boolean reached) {
this.reached = reached;
}
|
public void setRole(String role) {
this.role = role;
}
|
public String toString() {
String result = "CollectionEntry" +
MessageHelper.collectionInfoString( loadedPersister.getRole(), loadedKey );
if (currentPersister!=null) {
result += "- >" +
MessageHelper.collectionInfoString( currentPersister.getRole(), currentKey );
}
return result;
}
|
public boolean wasDereferenced() {
return getLoadedKey() == null;
}
|