package org.hibernate.collection.internal;
import java.io.Serializable;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
+import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.taxeditor.remoting.CdmEagerLoadingException;
+import eu.etaxonomy.taxeditor.remoting.cache.ProxyUtils;
+import eu.etaxonomy.taxeditor.service.ICachedCommonService;
+
/**
* Base class implementing {@link org.hibernate.collection.spi.PersistentCollection}
*
private static final Logger log = Logger.getLogger( AbstractPersistentCollection.class );
private static final long serialVersionUID = -7238232378593030571L;
-
+
private transient SessionImplementor session;
private boolean initialized;
private transient List<DelayedOperation> operationQueue;
private String sessionFactoryUuid;
private boolean specjLazyLoad = false;
- public final String getRole() {
+ @Override
+ public final String getRole() {
return role;
}
- public final Serializable getKey() {
+ @Override
+ public final Serializable getKey() {
return key;
}
- public final boolean isUnreferenced() {
+ @Override
+ public final boolean isUnreferenced() {
return role == null;
}
- public final boolean isDirty() {
+ @Override
+ public final boolean isDirty() {
return dirty;
}
- public final void clearDirty() {
+ @Override
+ public final void clearDirty() {
dirty = false;
}
- public final void dirty() {
+ @Override
+ public final void dirty() {
dirty = true;
}
- public final Serializable getStoredSnapshot() {
+ @Override
+ public final Serializable getStoredSnapshot() {
return storedSnapshot;
}
/**
* Is the initialized collection empty?
*/
- public abstract boolean empty();
+ @Override
+ public abstract boolean empty();
/**
* Called by any read-only method of the collection interface
return true;
}
else {
- boolean isExtraLazy = withTemporarySessionIfNeeded(
- new LazyInitializationWork<Boolean>() {
- @Override
- public Boolean doWork() {
- CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
-
- if ( entry != null ) {
- CollectionPersister persister = entry.getLoadedPersister();
- if ( persister.isExtraLazy() ) {
- if ( hasQueuedOperations() ) {
- session.flush();
+ // In remoting we are sure that session is null
+ // both when using property paths and switching off conversations
+ if(session == null && remoting) {
+ log.info("--> readSize, of " + getRole() + " with key " + getKey());
+ read();
+ } else {
+ boolean isExtraLazy = withTemporarySessionIfNeeded(
+ new LazyInitializationWork<Boolean>() {
+ @Override
+ public Boolean doWork() {
+ CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+
+ if ( entry != null ) {
+ CollectionPersister persister = entry.getLoadedPersister();
+ if ( persister.isExtraLazy() ) {
+ if ( hasQueuedOperations() ) {
+ session.flush();
+ }
+ cachedSize = persister.getSize( entry.getLoadedKey(), session );
+ return true;
+ }
+ else {
+ read();
}
- cachedSize = persister.getSize( entry.getLoadedKey(), session );
- return true;
}
- else {
- read();
+ else{
+ throwLazyInitializationExceptionIfNotConnected();
}
+ return false;
}
- else{
- throwLazyInitializationExceptionIfNotConnected();
- }
- return false;
}
- }
- );
- if ( isExtraLazy ) {
- return true;
+ );
+ if ( isExtraLazy ) {
+ return true;
+ }
}
}
}
if ( isTempSession ) {
// TODO: On the next major release, add an
// 'isJTA' or 'getTransactionFactory' method to Session.
- isJTA = session.getTransactionCoordinator()
+ /*isJTA = session.getTransactionCoordinator()
.getTransactionContext().getTransactionEnvironment()
.getTransactionFactory()
- .compatibleWithJtaSynchronization();
-
+ .compatibleWithJtaSynchronization();*/
+ isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
if ( !isJTA ) {
// Explicitly handle the transactions only if we're not in
// a JTA environment. A lazy loading temporary session can
// multiple transactions.
( ( Session) session ).beginTransaction();
}
-
+
session.getPersistenceContext().addUninitializedDetachedCollection(
session.getFactory().getCollectionPersister( getRole() ),
this
protected Boolean readIndexExistence(final Object index) {
if ( !initialized ) {
- Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
- new LazyInitializationWork<Boolean>() {
- @Override
- public Boolean doWork() {
- CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
- CollectionPersister persister = entry.getLoadedPersister();
- if ( persister.isExtraLazy() ) {
- if ( hasQueuedOperations() ) {
- session.flush();
+ // In remoting we are sure that session is null
+ // both when using property paths and switching off conversations
+ if(session == null && remoting) {
+ log.info("--> readIndexExistence, of " + getRole() + " with key " + getKey());
+ read();
+ } else {
+ Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
+ new LazyInitializationWork<Boolean>() {
+ @Override
+ public Boolean doWork() {
+ CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+ CollectionPersister persister = entry.getLoadedPersister();
+ if ( persister.isExtraLazy() ) {
+ if ( hasQueuedOperations() ) {
+ session.flush();
+ }
+ return persister.indexExists( entry.getLoadedKey(), index, session );
}
- return persister.indexExists( entry.getLoadedKey(), index, session );
- }
- else {
- read();
+ else {
+ read();
+ }
+ return null;
}
- return null;
}
- }
- );
- if ( extraLazyExistenceCheck != null ) {
- return extraLazyExistenceCheck;
+ );
+ if ( extraLazyExistenceCheck != null ) {
+ return extraLazyExistenceCheck;
+ }
}
}
return null;
protected Boolean readElementExistence(final Object element) {
if ( !initialized ) {
- Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
- new LazyInitializationWork<Boolean>() {
- @Override
- public Boolean doWork() {
- CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
- CollectionPersister persister = entry.getLoadedPersister();
- if ( persister.isExtraLazy() ) {
- if ( hasQueuedOperations() ) {
- session.flush();
+ // In remoting we are sure that session is null
+ // both when using property paths and switching off conversations
+ if(session == null && remoting) {
+ log.info("--> readElementExistence, of " + getRole() + " with key " + getKey());
+ read();
+
+ } else {
+ Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
+ new LazyInitializationWork<Boolean>() {
+ @Override
+ public Boolean doWork() {
+ CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+ CollectionPersister persister = entry.getLoadedPersister();
+ if ( persister.isExtraLazy() ) {
+ if ( hasQueuedOperations() ) {
+ session.flush();
+ }
+ return persister.elementExists( entry.getLoadedKey(), element, session );
}
- return persister.elementExists( entry.getLoadedKey(), element, session );
- }
- else {
- read();
+ else {
+ read();
+ }
+ return null;
}
- return null;
}
- }
- );
- if ( extraLazyExistenceCheck != null ) {
- return extraLazyExistenceCheck;
+ );
+ if ( extraLazyExistenceCheck != null ) {
+ return extraLazyExistenceCheck;
+ }
}
}
return null;
protected Object readElementByIndex(final Object index) {
if ( !initialized ) {
- class ExtraLazyElementByIndexReader implements LazyInitializationWork {
- private boolean isExtraLazy;
- private Object element;
+ // In remoting we are sure that session is null
+ // both when using property paths and switching off conversations
+ if(session == null && remoting) {
+ log.info("--> readElementByIndex, of " + getRole() + " with key " + getKey());
+ read();
- @Override
- public Object doWork() {
- CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
- CollectionPersister persister = entry.getLoadedPersister();
- isExtraLazy = persister.isExtraLazy();
- if ( isExtraLazy ) {
- if ( hasQueuedOperations() ) {
- session.flush();
+ } else {
+ class ExtraLazyElementByIndexReader implements LazyInitializationWork {
+ private boolean isExtraLazy;
+ private Object element;
+
+ @Override
+ public Object doWork() {
+ CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+ CollectionPersister persister = entry.getLoadedPersister();
+ isExtraLazy = persister.isExtraLazy();
+ if ( isExtraLazy ) {
+ if ( hasQueuedOperations() ) {
+ session.flush();
+ }
+ element = persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
}
- element = persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
- }
- else {
- read();
+ else {
+ read();
+ }
+ return null;
}
- return null;
}
- }
- ExtraLazyElementByIndexReader reader = new ExtraLazyElementByIndexReader();
- //noinspection unchecked
- withTemporarySessionIfNeeded( reader );
- if ( reader.isExtraLazy ) {
- return reader.element;
+ ExtraLazyElementByIndexReader reader = new ExtraLazyElementByIndexReader();
+ //noinspection unchecked
+ withTemporarySessionIfNeeded( reader );
+ if ( reader.isExtraLazy ) {
+ return reader.element;
+ }
}
}
return UNKNOWN;
/**
* After flushing, re-init snapshot state.
*/
- public void setSnapshot(Serializable key, String role, Serializable snapshot) {
+ @Override
+ public void setSnapshot(Serializable key, String role, Serializable snapshot) {
this.key = key;
this.role = role;
this.storedSnapshot = snapshot;
* After flushing, clear any "queued" additions, since the
* database state is now synchronized with the memory state.
*/
- public void postAction() {
+ @Override
+ public void postAction() {
operationQueue = null;
cachedSize = -1;
clearDirty();
/**
* return the user-visible collection (or array) instance
*/
- public Object getValue() {
+ @Override
+ public Object getValue() {
return this;
}
/**
* Called just before reading any rows from the JDBC result set
*/
- public void beginRead() {
+ @Override
+ public void beginRead() {
// override on some subclasses
initializing = true;
}
/**
* Called after reading all rows from the JDBC result set
*/
- public boolean endRead() {
+ @Override
+ public boolean endRead() {
//override on some subclasses
return afterInitialize();
}
- public boolean afterInitialize() {
+ @Override
+ public boolean afterInitialize() {
setInitialized();
//do this bit after setting initialized to true or it will recurse
if ( operationQueue != null ) {
* @throws LazyInitializationException if we cannot initialize
*/
protected final void initialize(final boolean writing) {
- if ( initialized ) {
- return;
- }
-
- withTemporarySessionIfNeeded(
- new LazyInitializationWork<Object>() {
- @Override
- public Object doWork() {
- session.initializeCollection( AbstractPersistentCollection.this, writing );
- return null;
- }
- }
- );
+ if ( initialized ) {
+ return;
+ }
+
+ // In remoting we are sure that session is null
+ // both when using property paths and switching off conversations
+ if(session == null && remoting) {
+ remoteInitialize();
+ } else {
+ withTemporarySessionIfNeeded(
+ new LazyInitializationWork<Object>() {
+ @Override
+ public Object doWork() {
+ session.initializeCollection( AbstractPersistentCollection.this, writing );
+ return null;
+ }
+ }
+ );
+ }
}
private void throwLazyInitializationExceptionIfNotConnected() {
* Could the application possibly have a direct reference to
* the underlying collection implementation?
*/
- public boolean isDirectlyAccessible() {
+ @Override
+ public boolean isDirectlyAccessible() {
return directlyAccessible;
}
*
* @return true if this was currently associated with the given session
*/
- public final boolean unsetSession(SessionImplementor currentSession) {
+ @Override
+ public final boolean unsetSession(SessionImplementor currentSession) {
prepareForPossibleSpecialSpecjInitialization();
if ( currentSession == this.session ) {
this.session = null;
* @throws HibernateException if the collection was already associated
* with another open session
*/
- public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
+ @Override
+ public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
if ( session == this.session ) {
return false;
}
/**
* Do we need to completely recreate this collection when it changes?
*/
- public boolean needsRecreate(CollectionPersister persister) {
+ @Override
+ public boolean needsRecreate(CollectionPersister persister) {
return false;
}
* To be called internally by the session, forcing
* immediate initialization.
*/
- public final void forceInitialization() throws HibernateException {
+ @Override
+ public final void forceInitialization() throws HibernateException {
if ( !initialized ) {
if ( initializing ) {
throw new AssertionFailure( "force initialize loading collection" );
/**
* Is this instance initialized?
*/
- public final boolean wasInitialized() {
+ @Override
+ public final boolean wasInitialized() {
return initialized;
}
- public boolean isRowUpdatePossible() {
+ @Override
+ public boolean isRowUpdatePossible() {
return true;
}
/**
* Does this instance have any "queued" additions?
*/
- public final boolean hasQueuedOperations() {
+ @Override
+ public final boolean hasQueuedOperations() {
return operationQueue != null;
}
/**
* Iterate the "queued" additions
*/
- public final Iterator queuedAdditionIterator() {
+ @Override
+ public final Iterator queuedAdditionIterator() {
if ( hasQueuedOperations() ) {
return new Iterator() {
int i = 0;
- public Object next() {
+ @Override
+ public Object next() {
return operationQueue.get( i++ ).getAddedInstance();
}
- public boolean hasNext() {
+ @Override
+ public boolean hasNext() {
return i < operationQueue.size();
}
- public void remove() {
+ @Override
+ public void remove() {
throw new UnsupportedOperationException();
}
};
/**
* Iterate the "queued" additions
*/
- @SuppressWarnings({"unchecked"})
+ @Override
+ @SuppressWarnings({"unchecked"})
public final Collection getQueuedOrphans(String entityName) {
if ( hasQueuedOperations() ) {
Collection additions = new ArrayList( operationQueue.size() );
* Called before inserting rows, to ensure that any surrogate keys
* are fully generated
*/
- public void preInsert(CollectionPersister persister) throws HibernateException {
+ @Override
+ public void preInsert(CollectionPersister persister) throws HibernateException {
}
/**
* Called after inserting a row, to fetch the natively generated id
*/
- public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {
+ @Override
+ public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {
}
/**
* get all "orphaned" elements
*/
- public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
+ @Override
+ public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
/**
* Get the current session
this.itr = itr;
}
- public boolean hasNext() {
+ @Override
+ public boolean hasNext() {
return itr.hasNext();
}
- public Object next() {
+ @Override
+ public Object next() {
return itr.next();
}
- public void remove() {
+ @Override
+ public void remove() {
write();
itr.remove();
}
this.itr = itr;
}
- @SuppressWarnings({"unchecked"})
+ @Override
+ @SuppressWarnings({"unchecked"})
public void add(Object o) {
write();
itr.add( o );
}
- public boolean hasNext() {
+ @Override
+ public boolean hasNext() {
return itr.hasNext();
}
- public boolean hasPrevious() {
+ @Override
+ public boolean hasPrevious() {
return itr.hasPrevious();
}
- public Object next() {
+ @Override
+ public Object next() {
return itr.next();
}
- public int nextIndex() {
+ @Override
+ public int nextIndex() {
return itr.nextIndex();
}
- public Object previous() {
+ @Override
+ public Object previous() {
return itr.previous();
}
- public int previousIndex() {
+ @Override
+ public int previousIndex() {
return itr.previousIndex();
}
- public void remove() {
+ @Override
+ public void remove() {
write();
itr.remove();
}
- @SuppressWarnings({"unchecked"})
+ @Override
+ @SuppressWarnings({"unchecked"})
public void set(Object o) {
write();
itr.set( o );
this.set = set;
}
- @SuppressWarnings({"unchecked"})
+ @Override
+ @SuppressWarnings({"unchecked"})
public boolean add(Object o) {
write();
return set.add( o );
}
- @SuppressWarnings({"unchecked"})
+ @Override
+ @SuppressWarnings({"unchecked"})
public boolean addAll(Collection c) {
write();
return set.addAll( c );
}
- public void clear() {
+ @Override
+ public void clear() {
write();
set.clear();
}
- public boolean contains(Object o) {
+ @Override
+ public boolean contains(Object o) {
return set.contains( o );
}
- public boolean containsAll(Collection c) {
+ @Override
+ public boolean containsAll(Collection c) {
return set.containsAll( c );
}
- public boolean isEmpty() {
+ @Override
+ public boolean isEmpty() {
return set.isEmpty();
}
- public Iterator iterator() {
+ @Override
+ public Iterator iterator() {
return new IteratorProxy( set.iterator() );
}
- public boolean remove(Object o) {
+ @Override
+ public boolean remove(Object o) {
write();
return set.remove( o );
}
- public boolean removeAll(Collection c) {
+ @Override
+ public boolean removeAll(Collection c) {
write();
return set.removeAll( c );
}
- public boolean retainAll(Collection c) {
+ @Override
+ public boolean retainAll(Collection c) {
write();
return set.retainAll( c );
}
- public int size() {
+ @Override
+ public int size() {
return set.size();
}
- public Object[] toArray() {
+ @Override
+ public Object[] toArray() {
return set.toArray();
}
- @SuppressWarnings({"unchecked"})
+ @Override
+ @SuppressWarnings({"unchecked"})
public Object[] toArray(Object[] array) {
return set.toArray( array );
}
}
}
- public Object getIdentifier(Object entry, int i) {
+ @Override
+ public Object getIdentifier(Object entry, int i) {
throw new UnsupportedOperationException();
}
- public Object getOwner() {
+ @Override
+ public Object getOwner() {
return owner;
}
- public void setOwner(Object owner) {
+ @Override
+ public void setOwner(Object owner) {
this.owner = owner;
}
+ /** ------ Below is section of code which makes remote service calls ----- */
+ // The affected methods are :
+ // initialize(final boolean writing)
+ // readSize()
+ // readIndexExistence(final Object index)
+ // readElementExistence(final Object element)
+ // readElementByIndex(final Object index)
+
+ private static CdmApplicationRemoteConfiguration configuration;
+ private static boolean remoting = false;
+
+ public static void setConfiguration(CdmApplicationRemoteConfiguration conf) {
+ remoting = true;
+ configuration = conf;
+ }
+
+
+ private void remoteInitialize() {
+
+ if (getOwner() != null && !initialized) {
+
+ try {
+ String role = getRole();
+ String fieldName = role.substring(role.lastIndexOf(".") + 1);
+ log.info("--> Remote Lazy Initializing Collection " + getRole() + " , owner : " + getOwner().getClass() + "/" + getKey() + " , field : " + fieldName);
+ Object owner = getOwner();
+ CdmBase cdmBase;
+ if(owner instanceof CdmBase) {
+ cdmBase = (CdmBase)owner;
+ } else {
+ throw new HibernateException("Owner of persistent collection is not a cdm entity");
+ }
+ if(configuration == null) {
+ throw new HibernateException("CdmApplicationRemoteConfiguration not initialized (null)");
+ }
+ ICachedCommonService cachedCommonService = configuration.getCachedCommonService();
+ if(cachedCommonService == null) {
+ throw new HibernateException("commonService not initialized (null)");
+ }
+
+ //Object obj = ProxyUtils.deproxy(cachedCommonService.initializeCollection(this));
+ Object obj = ProxyUtils.deproxy(cachedCommonService.initializeCollection(cdmBase.getUuid(), fieldName));
+ if(ProxyUtils.isProxy(obj)) {
+ throw new HibernateException("Persistent Collection initialized but is still a proxy");
+ }
+ afterInitialize();
+
+ Class<?> clazz = getClass();
+ if (clazz != null) {
+ //CollectionField cf = cachedCommonService.getCollectionField(col);
+ //cachedCommonService.updatePersistentCollection(cf);
+ Object collectionType = ProxyUtils.getCollectionType(obj);
+ Field field = clazz.getDeclaredField(collectionType.toString());
+ field.setAccessible(true);
+ field.set(this, obj);
+ ProxyUtils.setRoleValueInOwner(owner, role, obj);
+
+ }
+ } catch (Exception ex) {
+ throw new CdmEagerLoadingException(ex);
+ }
+ }
+ }
+
+
+
}