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 java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
import javax.naming.NamingException;
import org.hibernate.type.Type;
import org.jboss.logging.Logger;
-import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteController;
-import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration;
-import eu.etaxonomy.cdm.api.service.ICommonService;
-import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText;
+import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration;
+import eu.etaxonomy.cdm.cache.ProxyUtils;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.taxeditor.remoting.CdmEagerLoadingException;
+import eu.etaxonomy.taxeditor.service.ICachedCommonService;
/**
* Base class implementing {@link org.hibernate.collection.spi.PersistentCollection}
*
+ * This a extended copy of the original class from hibernate. It has been extended to
+ * allow making remote service calls to spring httpinvoker services (see section at the bottom
+ * of this class).
+ *
+ *
* @author Gavin King
+ * @author Cherian Mathew
*/
public abstract class AbstractPersistentCollection implements Serializable, PersistentCollection {
private static final Logger log = Logger.getLogger( AbstractPersistentCollection.class );
- private static final long serialVersionUID = -7238232378593030571L;
+ /**
+ * <b>IMPORTANT:</b><br>
+ * This serialVersionUID must be kept in sync with the serialVersionUID which is generated
+ * on the fly for serialized AbstractPersistentCollection objects coming from the httpInvoker
+ * service.
+ * This is most probably necessary after updating hibernate to a newer version. In any case
+ * it the need for updating this <code>serialVersionUID</code> becomes obvious when the attempt
+ * to connect to the server side fails with an <code>InvalidClassException</code>:
+ *
+ * <pre>
+ * java.io.InvalidClassException: org.hibernate.collection.internal.AbstractPersistentCollection;
+ * local class incompatible:
+ * stream classdesc serialVersionUID = 2742261122392386159,
+ * local class serialVersionUID = -7238232378593030571
+ * </pre>
+ * The correct <code>serialVersionUID</code> is the <code>stream classdesc serialVersionUID</code>
+ * from the error message.
+ */
+ private static final long serialVersionUID = 2742261122392386159L;
private transient SessionImplementor session;
private boolean initialized;
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
* @throws LazyInitializationException if we cannot initialize
*/
protected final void initialize(final boolean writing) {
- // In remoting we are sure that session is null
- // both when using property paths and switching off conversations
- if(session == null && remoting) {
- remoteInitialize();
- }
-
- 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() {
// readElementExistence(final Object element)
// readElementByIndex(final Object index)
- private static ICdmApplicationConfiguration configuration;
+ private static CdmApplicationRemoteConfiguration configuration;
private static boolean remoting = false;
- public static void setConfiguration(ICdmApplicationConfiguration conf) {
+ public static void setConfiguration(CdmApplicationRemoteConfiguration conf) {
+ remoting = true;
configuration = conf;
-
- if(conf instanceof CdmApplicationRemoteController) {
- remoting = true;
- } else {
- remoting = false;
- }
}
try {
String role = getRole();
String fieldName = role.substring(role.lastIndexOf(".") + 1);
- log.info("--> Remote Lazy Initializing " + getRole() + " , key : " + getKey() + " , field : " + fieldName);
+ 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)");
}
- ICommonService commonService = configuration.getCommonService();
- if(commonService == null) {
+ ICachedCommonService cachedCommonService = configuration.getCachedCommonService();
+ if(cachedCommonService == null) {
throw new HibernateException("commonService not initialized (null)");
}
-// PersistentCollection col = commonService.initializeCollection(this);
-// afterInitialize();
-//
-// Class<?> clazz = getClass();
-// if (clazz != null) {
-// CollectionField cf = getCollectionField(col);
-// Field field = clazz.getDeclaredField(cf.getFieldName());
-// field.setAccessible(true);
-// field.set(this, cf.getCollection());
-// }
- } catch (Exception ex) {
- log.warn(ex.getMessage());
- }
- log.warn("This code is invalid");
- }
- }
-
+ //Object obj = ProxyUtils.deproxyIfInitialized(cachedCommonService.initializeCollection(this));
+ Object obj = ProxyUtils.deproxyIfInitialized(cachedCommonService.initializeCollection(cdmBase.getUuid(), fieldName));
+ if(ProxyUtils.isUninitializedProxy(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, clazz);
+ Field field = clazz.getDeclaredField(collectionType.toString());
+ field.setAccessible(true);
+ field.set(this, obj);
+ ProxyUtils.setRoleValueInOwner(owner, role, obj);
- private CollectionField getCollectionField(PersistentCollection pc) {
- if(pc != null) {
- if(pc instanceof PersistentSet) {
- return new CollectionField(new HashSet((Set)pc), "set");
- }
- if(pc instanceof PersistentSortedSet) {
- return new CollectionField(new TreeSet((Set)pc), "set");
- }
- if(pc instanceof PersistentList) {
- return new CollectionField(new ArrayList((List)pc), "list");
- }
- if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
- return new CollectionField(new HashMap((Map)pc), "map");
- }
- if(pc instanceof PersistentSortedMap) {
- return new CollectionField(new TreeMap((Map)pc), "map");
+ }
+ } catch (Exception ex) {
+ throw new CdmEagerLoadingException(ex);
}
}
- return null;
}
- private String getCollectionFieldName(PersistentCollection pc) {
- if(pc != null) {
- if(pc instanceof PersistentSet || pc instanceof PersistentSortedSet) {
- return "set";
- }
- if(pc instanceof PersistentList) {
- return "list";
- }
- if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) {
- return "map";
- }
- }
- return null;
- }
-
- private class CollectionField {
- private final Object col;
- private final String fieldName;
- public CollectionField(Object col, String fieldName) {
- this.col = col;
- this.fieldName = fieldName;
- }
-
- public Object getCollection() {
- return this.col;
- }
-
- public String getFieldName() {
- return this.fieldName;
- }
- }
-
- public static boolean isInitialized(List list) {
- return ((AbstractPersistentCollection)list).initialized;
- }
-
- public static boolean isInitialized(Map map) {
- return ((AbstractPersistentCollection)map).initialized;
- }
-
- public static boolean isInitialized(Set set) {
- return ((AbstractPersistentCollection)set).initialized;
- }
}