Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java')
-rwxr-xr-xhibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java244
1 files changed, 244 insertions, 0 deletions
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java
new file mode 100755
index 000000000..a1292e511
--- /dev/null
+++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/elist/HibernatePersistableFeatureMap.java
@@ -0,0 +1,244 @@
+/**
+ * <copyright>
+ *
+ * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Martin Taal
+ * </copyright>
+ *
+ * $Id: HibernatePersistableFeatureMap.java,v 1.15 2009/11/02 10:24:50 mtaal Exp $
+ */
+
+package org.eclipse.emf.teneo.hibernate.mapping.elist;
+
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.teneo.EContainerRepairControl;
+import org.eclipse.emf.teneo.extension.ExtensionPoint;
+import org.eclipse.emf.teneo.hibernate.HbMapperException;
+import org.eclipse.emf.teneo.hibernate.SessionWrapper;
+import org.eclipse.emf.teneo.hibernate.resource.HibernateResource;
+import org.eclipse.emf.teneo.mapping.elist.PersistableFeatureMap;
+import org.eclipse.emf.teneo.resource.StoreResource;
+import org.eclipse.emf.teneo.util.AssertUtil;
+import org.hibernate.Session;
+import org.hibernate.collection.AbstractPersistentCollection;
+import org.hibernate.collection.PersistentBag;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentList;
+
+/**
+ * Implements the hibernate persistable elist.
+ *
+ * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
+ * @version $Revision: 1.15 $
+ */
+
+public class HibernatePersistableFeatureMap extends PersistableFeatureMap implements ExtensionPoint {
+ /**
+ * Serial Version ID
+ */
+ private static final long serialVersionUID = -1916994464446630140L;
+
+ /** The logger */
+ private static Log log = LogFactory.getLog(HibernatePersistableFeatureMap.class);
+
+ /** Constructor */
+ public HibernatePersistableFeatureMap(InternalEObject owner, EStructuralFeature feature, List<FeatureMap.Entry> list) {
+ super(owner, feature, list);
+
+ if (isLoaded()) {
+ for (Entry entry : getDelegate()) {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) entry;
+ if (!fme.belongsToFeatureMap(this)) {
+ fme.setFeatureMap(this);
+ }
+ }
+ }
+ }
+
+ /** Returns the element type to be used */
+ @Override
+ protected Class<? extends FeatureMap.Entry> determineElementType() {
+ return HibernateFeatureMapEntry.class;
+ }
+
+ /** OVerridden to create the correct featuremap entry */
+ @Override
+ protected FeatureMap.Entry createEntry(EStructuralFeature eStructuralFeature, Object value) {
+ final HibernateFeatureMapEntry entry = new HibernateFeatureMapEntry();
+ entry.setFeatureValue(eStructuralFeature, value, this);
+ return entry;
+ }
+
+ /** Shortcut to replace entries */
+ protected FeatureMap.Entry replaceEntry(Object entry) {
+ if (entry instanceof HibernateFeatureMapEntry && ((HibernateFeatureMapEntry) entry).belongsToFeatureMap(this)) {
+ return (HibernateFeatureMapEntry) entry;
+ }
+
+ final FeatureMap.Entry emfEntry = (FeatureMap.Entry) entry;
+ final HibernateFeatureMapEntry fme = new HibernateFeatureMapEntry();
+ fme.setFeatureValue(emfEntry.getEStructuralFeature(), emfEntry.getValue(), this);
+ return fme;
+ }
+
+ /** If the delegate has been initialized */
+ public boolean isInitialized() {
+ return ((PersistentCollection) delegate).wasInitialized();
+ }
+
+ /**
+ * Override isLoaded to check if the delegate lists was not already loaded by hibernate behind the scenes, this
+ * happens with eagerly loaded lists.
+ */
+ @Override
+ public boolean isLoaded() {
+ if (delegate instanceof AbstractPersistentCollection) {
+ if (((AbstractPersistentCollection) delegate).wasInitialized()) {
+ // delegate is loaded in case of subselect or eager loading
+ if (isLoading()) {
+ // probably are we doing this already return
+ return false;
+ }
+ log.debug("Persistentlist already initialized, probably eagerly loaded: " + getLogString());
+ try {
+ setIsLoading(true);
+ // do load to load the resource
+ doLoad();
+ setIsLoaded(true);
+ } finally {
+ setIsLoading(false);
+ }
+ }
+ }
+ return super.isLoaded();
+ }
+
+ /** Do the actual load can be overridden, called from the subclass */
+ @Override
+ protected synchronized void doLoad() {
+ AssertUtil.assertTrue("EList " + logString, !isLoaded());
+
+ SessionWrapper sessionWrapper = null;
+ boolean controlsSession = false;
+ boolean err = true;
+ try {
+ final Resource res = owner.eResource();
+
+ if (res != null && res instanceof HibernateResource) {
+ sessionWrapper = ((HibernateResource) res).getSessionWrapper();
+ if (res.isLoaded()) { // resource is loaded reopen transaction
+ if (!sessionWrapper.isTransactionActive()) {
+ log.debug("Reconnecting session to read a lazy collection, Featuremap: " + logString);
+ controlsSession = true;
+ sessionWrapper.beginTransaction();
+ sessionWrapper.setFlushModeManual();
+ } else {
+ log.debug("Resource session is still active, using it");
+ }
+ } else {
+ log.debug("Featuremap uses session from resource, " + logString);
+ }
+ } else {
+ log.debug("EList is not loaded in session context");
+ }
+
+ Object[] objs = delegate.toArray(); // this forces the load
+
+ // set the owner of the feature map entries
+ // set the econtainer
+ for (Object element : objs) {
+ final HibernateFeatureMapEntry fme = (HibernateFeatureMapEntry) element;
+ fme.setFeatureMap(this);
+
+ if (fme.getEStructuralFeature() instanceof EReference
+ && ((EReference) fme.getEStructuralFeature()).isContainment()) {
+ final InternalEObject eobj = (InternalEObject) fme.getValue();
+ if (eobj != null) {
+ EContainerRepairControl.setContainer(owner, eobj, fme.getEStructuralFeature());
+ if (res != null && res instanceof StoreResource
+ && fme.getEStructuralFeature() instanceof EReference) {
+ ((StoreResource) res).addToContentOrAttach((InternalEObject) fme.getValue(),
+ (EReference) fme.getEStructuralFeature());
+ }
+ }
+ }
+ }
+
+ err = false;
+ log.debug("Loaded " + objs.length + " from backend store for " + logString);
+ } finally {
+ if (controlsSession) {
+ if (err) {
+ sessionWrapper.rollbackTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ } else {
+ // a bit rough but delete from the persitence context
+ // otherwise
+ // hibernate will think that this collection is not attached
+ // to anything and
+ // will delete me
+ // getSession().getPersistenceContext().getCollectionEntries().remove(this);
+ sessionWrapper.commitTransaction();
+ sessionWrapper.restorePreviousFlushMode();
+ }
+ }
+ }
+ }
+
+ /** Overridden because general list type is not supported as a replacement */
+ @Override
+ public void replaceDelegate(List<FeatureMap.Entry> newDelegate) {
+ if (newDelegate instanceof PersistentList) {
+ AssertUtil.assertTrue("This elist " + logString + " contains a different list than the " + " passed list",
+ ((PersistentList) newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else if (newDelegate instanceof PersistentBag) {
+ AssertUtil.assertTrue("This elist " + logString + " contains a different list than the " + " passed list",
+ ((PersistentBag) newDelegate).isWrapper(delegate));
+ super.replaceDelegate(newDelegate);
+ } else {
+ throw new HbMapperException("Type " + newDelegate.getClass().getName() + " can not be "
+ + " used as a replacement for elist " + logString);
+ }
+ }
+
+ /** Returns true if the wrapped list is a persistency layer specific list */
+ @Override
+ public boolean isPersistencyWrapped() {
+ return delegate instanceof PersistentCollection;
+ }
+
+ @Override
+ protected Entry delegateRemove(int index) {
+ final Entry old = super.delegateRemove(index);
+
+ if (old.getEStructuralFeature() instanceof EReference && getDelegate() instanceof PersistentList) {
+ final PersistentList pl = (PersistentList) getDelegate();
+ final EReference eref = (EReference) old.getEStructuralFeature();
+ if (eref.isContainment()) {
+ ((Session) pl.getSession()).delete(old.getValue());
+ }
+ }
+ return old;
+ }
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ // TODO Auto-generated method stub
+ return super.clone();
+ }
+} \ No newline at end of file

Back to the top