You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2013/10/04 09:33:44 UTC

[2/2] git commit: ISIS-553: view model support

ISIS-553: view model support

* container.newViewModelInstance(SomeClass.class, "id")
* ViewModel interface (replacing @ViewModel annotation)

related
* support for @PersistenceCapable(identityType=NONDURABLE)
  eg as per http://www.datanucleus.org/products/accessplatform_3_2/datastores/rdbms_views.html

also:
* MandatoryFromJdoColumnAnnotationFacetFactory (as a metamodel validator)
  - no longer raises a violation for entities without the @PersistenceCapable annotation
  - does not raise a violation for NONDURABLE entities
  - does not raise a violation for properties with JDO @NotPersistent annotation


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/6ede1ba8
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/6ede1ba8
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/6ede1ba8

Branch: refs/heads/master
Commit: 6ede1ba8f26462ca21a88707c69f437343e87185
Parents: 1dd9e81
Author: Dan Haywood <da...@apache.org>
Authored: Fri Oct 4 08:33:24 2013 +0100
Committer: Dan Haywood <da...@apache.org>
Committed: Fri Oct 4 08:33:24 2013 +0100

----------------------------------------------------------------------
 ...ataNucleusPersistenceMechanismInstaller.java |   2 +
 .../persistence/FrameworkSynchronizer.java      |   6 +-
 .../DataNucleusPojoRecreator.java               |   2 +-
 .../spi/DataNucleusIdentifierGenerator.java     |  12 +-
 ...toryFromJdoColumnAnnotationFacetFactory.java |  15 ++-
 .../JdoNotPersistentAnnotationFacetFactory.java |  48 +++++++
 .../notpersistent/JdoNotPersistentFacet.java    |  34 +++++
 .../JdoNotPersistentFacetAbstract.java          |  36 +++++
 .../JdoNotPersistentFacetAnnotation.java        |  30 +++++
 .../JdoNotPersistentFacetImpl.java              |  30 +++++
 ...etDerivedFromJdoNotPersistentAnnotation.java |  31 +++++
 ...FacetDerivedFromJdoPrimaryKeyAnnotation.java |   2 +-
 .../validator/JdoMetaModelValidator.java        |   7 +-
 ...NotPersistentAnnotationFacetFactoryTest.java | 132 +++++++++++++++++++
 .../SimpleObjectWithNotPersistentColumn.java    |  36 +++++
 ...JdoPrimaryKeyAnnotationFacetFactoryTest.java |   8 +-
 .../restfulobjects/server/util/OidUtils.java    |  19 ++-
 .../apache/isis/applib/AbstractViewModel.java   |  41 ++++++
 .../isis/applib/DomainObjectContainer.java      |  10 +-
 .../isis/applib/annotation/ViewModel.java       |  36 +++--
 .../metamodel/adapter/DomainObjectServices.java |   3 +
 .../metamodel/adapter/oid/AggregatedOid.java    |   8 --
 .../metamodel/adapter/oid/CollectionOid.java    |   9 --
 .../isis/core/metamodel/adapter/oid/Oid.java    |  19 ++-
 .../metamodel/adapter/oid/OidMarshaller.java    |  26 +++-
 .../core/metamodel/adapter/oid/ParentedOid.java |  19 +++
 .../metamodel/adapter/oid/RootOidDefault.java   |  19 ++-
 .../facets/object/viewmodel/ViewModelFacet.java |   2 +
 .../noruntime/RuntimeContextNoRuntime.java      |   7 +-
 .../container/DomainObjectContainerDefault.java |  22 +++-
 .../ViewModelAnnotationFacetFactory.java        |  46 -------
 .../annotation/ViewModelFacetAnnotation.java    |  31 -----
 .../annotation/ViewModelFacetForInterface.java  |  38 ++++++
 .../ViewModelIntefaceFacetFactory.java          |  45 +++++++
 .../dflt/ProgrammingModelFacetsJava5.java       |   4 +-
 .../ViewModelAnnotationFacetFactoryTest.java    |  61 ---------
 .../ViewModelInteraceFacetFactoryTest.java      |  70 ++++++++++
 .../adaptermanager/AdapterManagerDefault.java   |  12 +-
 .../adaptermanager/PojoRecreatorDefault.java    |  22 +++-
 .../internal/RuntimeContextFromSession.java     |   6 +
 .../system/persistence/OidGenerator.java        |  21 +--
 .../system/persistence/PersistenceSession.java  |  24 +++-
 .../tck/dom/viewmodels/SimpleViewModel.java     |  22 +++-
 43 files changed, 848 insertions(+), 225 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
index d76ba97..bd14bd7 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
@@ -51,6 +51,7 @@ import org.apache.isis.objectstore.jdo.metamodel.facets.object.persistencecapabl
 import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryAnnotationFacetFactory;
 import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.BigDecimalDerivedFromJdoColumnAnnotationFacetFactory;
 import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.MandatoryFromJdoColumnAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent.JdoNotPersistentAnnotationFacetFactory;
 import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.JdoPrimaryKeyAnnotationFacetFactory;
 import org.apache.isis.objectstore.jdo.metamodel.specloader.validator.JdoMetaModelValidator;
 
@@ -186,6 +187,7 @@ public class DataNucleusPersistenceMechanismInstaller extends PersistenceMechani
         programmingModel.addFactory(JdoEmbeddedOnlyAnnotationFacetFactory.class);
         
         programmingModel.addFactory(JdoPrimaryKeyAnnotationFacetFactory.class);
+        programmingModel.addFactory(JdoNotPersistentAnnotationFacetFactory.class);
         programmingModel.addFactory(JdoDiscriminatorAnnotationFacetFactory.class);
         
         programmingModel.addFactory(JdoQueryAnnotationFacetFactory.class);

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
index b9f9132..29bb192 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/FrameworkSynchronizer.java
@@ -104,7 +104,7 @@ public class FrameworkSynchronizer {
                     }
                 } else {
                     final OidGenerator oidGenerator = getOidGenerator();
-                    originalOid = oidGenerator.createPersistent(pojo, null);
+                    originalOid = oidGenerator.createPersistentOrViewModelOid(pojo, null);
                     
                     // it appears to be possible that there is already an adapter for this Oid, 
                     // ie from ObjectStore#resolveImmediately()
@@ -147,7 +147,7 @@ public class FrameworkSynchronizer {
                 Class<? extends CallbackFacet> callbackFacetClass;
                 if (isisOid.isTransient()) {
                     // persisting
-                    final RootOid persistentOid = getOidGenerator().createPersistent(pojo, isisOid);
+                    final RootOid persistentOid = getOidGenerator().createPersistentOrViewModelOid(pojo, isisOid);
                     
                     getPersistenceSession().remapAsPersistent(adapter, persistentOid);
 
@@ -220,7 +220,7 @@ public class FrameworkSynchronizer {
                 if(getJdoPersistenceManager().getObjectId(pojo) == null) {
                     return null;
                 }
-                final RootOid oid = getPersistenceSession().getOidGenerator().createPersistent(pojo, null);
+                final RootOid oid = getPersistenceSession().getOidGenerator().createPersistentOrViewModelOid(pojo, null);
                 final ObjectAdapter adapter = getPersistenceSession().mapRecreatedPojo(oid, pojo);
                 return adapter;
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
index edd883d..cf14157 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/adaptermanager/DataNucleusPojoRecreator.java
@@ -32,7 +32,7 @@ public class DataNucleusPojoRecreator implements PojoRecreator {
     
     @Override
     public Object recreatePojo(TypedOid oid) {
-        if(oid.isTransient()) {
+        if(oid.isTransient() || oid.isViewModel()) {
             return delegate.recreatePojo(oid);
         }
         return getObjectStore().loadPojo(oid);

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
index 3746565..c152b51 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/persistence/spi/DataNucleusIdentifierGenerator.java
@@ -26,6 +26,7 @@ import javax.jdo.spi.PersistenceCapable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.applib.annotation.ViewModel;
 import org.apache.isis.core.commons.debug.DebugBuilder;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
@@ -47,6 +48,12 @@ public class DataNucleusIdentifierGenerator implements IdentifierGenerator {
 
     @Override
     public String createTransientIdentifierFor(ObjectSpecId objectSpecId, Object pojo) {
+        
+        if(pojo instanceof ViewModel) {
+            ViewModel viewModel = (ViewModel) pojo;
+            return viewModel.viewModelMemento();
+        }
+
         return UUID.randomUUID().toString();
     }
 
@@ -65,8 +72,11 @@ public class DataNucleusIdentifierGenerator implements IdentifierGenerator {
             return "1";
         }
         
+        if(pojo instanceof ViewModel) {
+            ViewModel viewModel = (ViewModel) pojo;
+            return viewModel.viewModelMemento();
+        }
         final Object jdoOid = getJdoPersistenceManager().getObjectId(pojo);
-        
         return JdoObjectIdSerializer.toOidIdentifier(jdoOid);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
index d03d51d..19f76f4 100644
--- a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/column/MandatoryFromJdoColumnAnnotationFacetFactory.java
@@ -21,6 +21,8 @@ package org.apache.isis.objectstore.jdo.metamodel.facets.prop.column;
 import java.util.List;
 
 import javax.jdo.annotations.Column;
+import javax.jdo.annotations.IdentityType;
+import javax.jdo.spi.PersistenceCapable;
 
 import com.google.common.base.Strings;
 
@@ -41,6 +43,8 @@ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVis
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorVisiting.Visitor;
 import org.apache.isis.core.metamodel.specloader.validator.ValidationFailures;
 import org.apache.isis.core.progmodel.facets.properties.mandatory.annotation.MandatoryFacetExplicitForProperty;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableFacet;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent.JdoNotPersistentFacet;
 import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.OptionalFacetDerivedFromJdoPrimaryKeyAnnotation;
 
 
@@ -118,9 +122,18 @@ public class MandatoryFromJdoColumnAnnotationFacetFactory extends FacetFactoryAb
 
             private void validate(ObjectSpecification objectSpec, ValidationFailures validationFailures) {
                 
-                List<ObjectAssociation> associations = objectSpec.getAssociations(Contributed.EXCLUDED, ObjectAssociation.Filters.PROPERTIES);
+                final JdoPersistenceCapableFacet pcFacet = objectSpec.getFacet(JdoPersistenceCapableFacet.class);
+                if(pcFacet==null || pcFacet.getIdentityType() == IdentityType.NONDURABLE) {
+                    return;
+                }
+                
+                final List<ObjectAssociation> associations = objectSpec.getAssociations(Contributed.EXCLUDED, ObjectAssociation.Filters.PROPERTIES);
                 for (ObjectAssociation association : associations) {
                     
+                    // skip checks if annotated with JDO @NotPersistent
+                    if(association.containsDoOpFacet(JdoNotPersistentFacet.class)) {
+                        return;
+                    }
                     
                     MandatoryFacet facet = association.getFacet(MandatoryFacet.class);
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentAnnotationFacetFactory.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentAnnotationFacetFactory.java
new file mode 100644
index 0000000..a7c5583
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentAnnotationFacetFactory.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import javax.jdo.annotations.NotPersistent;
+import javax.jdo.annotations.PrimaryKey;
+
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.Annotations;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.FacetedMethod;
+
+
+public class JdoNotPersistentAnnotationFacetFactory extends FacetFactoryAbstract {
+
+    public JdoNotPersistentAnnotationFacetFactory() {
+        super(FeatureType.PROPERTIES_ONLY);
+    }
+
+    @Override
+    public void process(ProcessMethodContext processMethodContext) {
+        final NotPersistent annotation = Annotations.getAnnotation(processMethodContext.getMethod(), NotPersistent.class);
+        if (annotation == null) {
+            return;
+        }
+
+        final FacetedMethod holder = processMethodContext.getFacetHolder();
+        FacetUtil.addFacet(new JdoNotPersistentFacetAnnotation(holder));
+        FacetUtil.addFacet(new NotPersistedFacetDerivedFromJdoNotPersistentAnnotation(holder));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacet.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacet.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacet.java
new file mode 100644
index 0000000..0d31a95
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacet.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import javax.jdo.annotations.PrimaryKey;
+
+import org.apache.isis.core.metamodel.facets.MarkerFacet;
+
+
+/**
+ * Corresponds to the property with the {@link PrimaryKey} annotation.
+ * <p>
+ * The JDO {@link PrimaryKey} annotation is used internally the JDO object store to
+ * create the {@link Oid}.
+ */
+public interface JdoNotPersistentFacet extends MarkerFacet {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAbstract.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAbstract.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAbstract.java
new file mode 100644
index 0000000..ff5e211
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAbstract.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.MarkerFacetAbstract;
+
+
+public abstract class JdoNotPersistentFacetAbstract extends MarkerFacetAbstract implements
+        JdoNotPersistentFacet {
+
+    public static Class<? extends Facet> type() {
+        return JdoNotPersistentFacet.class;
+    }
+
+    public JdoNotPersistentFacetAbstract(final FacetHolder holder) {
+        super(JdoNotPersistentFacetAbstract.type(), holder);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAnnotation.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAnnotation.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAnnotation.java
new file mode 100644
index 0000000..10c4e96
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetAnnotation.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+
+public class JdoNotPersistentFacetAnnotation extends JdoNotPersistentFacetImpl {
+
+    public JdoNotPersistentFacetAnnotation(final FacetHolder holder) {
+        super(holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetImpl.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetImpl.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetImpl.java
new file mode 100644
index 0000000..752d4c3
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/JdoNotPersistentFacetImpl.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+
+
+public class JdoNotPersistentFacetImpl extends JdoNotPersistentFacetAbstract {
+
+    public JdoNotPersistentFacetImpl(final FacetHolder holder) {
+        super(holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/NotPersistedFacetDerivedFromJdoNotPersistentAnnotation.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/NotPersistedFacetDerivedFromJdoNotPersistentAnnotation.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/NotPersistedFacetDerivedFromJdoNotPersistentAnnotation.java
new file mode 100644
index 0000000..1e9a8f4
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/NotPersistedFacetDerivedFromJdoNotPersistentAnnotation.java
@@ -0,0 +1,31 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.notpersisted.NotPersistedFacetAbstract;
+
+
+public class NotPersistedFacetDerivedFromJdoNotPersistentAnnotation extends NotPersistedFacetAbstract {
+
+    public NotPersistedFacetDerivedFromJdoNotPersistentAnnotation(final FacetHolder holder) {
+        super(holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/DisabledFacetDerivedFromJdoPrimaryKeyAnnotation.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/DisabledFacetDerivedFromJdoPrimaryKeyAnnotation.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/DisabledFacetDerivedFromJdoPrimaryKeyAnnotation.java
index 0a133fa..3e89765 100644
--- a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/DisabledFacetDerivedFromJdoPrimaryKeyAnnotation.java
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/DisabledFacetDerivedFromJdoPrimaryKeyAnnotation.java
@@ -25,7 +25,7 @@ import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacetImpl;
 
 
 /**
- * Derived from being {@link Transient}.
+ * Derived by the presence of the primary key.
  */
 public class DisabledFacetDerivedFromJdoPrimaryKeyAnnotation extends DisabledFacetImpl {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/specloader/validator/JdoMetaModelValidator.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/specloader/validator/JdoMetaModelValidator.java b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/specloader/validator/JdoMetaModelValidator.java
index d607b32..9248df7 100644
--- a/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/specloader/validator/JdoMetaModelValidator.java
+++ b/component/objectstore/jdo/jdo-metamodel/src/main/java/org/apache/isis/objectstore/jdo/metamodel/specloader/validator/JdoMetaModelValidator.java
@@ -75,12 +75,17 @@ public class JdoMetaModelValidator extends MetaModelValidatorComposite {
                 if(identityType == IdentityType.APPLICATION) {
                     // ok
                     
+                } else if(identityType == IdentityType.NONDURABLE) {
+                    // ok; for use with view models (http://www.datanucleus.org/products/accessplatform_3_2/datastores/rdbms_views.html)
+                    
                 } else if(identityType == IdentityType.DATASTORE || identityType == IdentityType.UNSPECIFIED) {
                     
                     // TODO: ensure that DATASTORE has recognised @DatastoreIdentity attribute
                     
                 } else {
-                    validationFailures.add("DataNucleus object store: %s must be annotated with @PersistenceCapable, with an identityType of either DATASTORE or UNSPECIFIED or APPLICATION (has an identityType of %s)", objSpec.getFullIdentifier(), identityType);
+                    // in fact, at the time of writing there are no others, so this is theoretical in case there is 
+                    // a future change to the JDO spec
+                    validationFailures.add("DataNucleus object store: %s is annotated with @PersistenceCapable but with an unrecognized identityType (%s)", objSpec.getFullIdentifier(), identityType);
                 }
                 
                 return true;

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/GivenJdoNotPersistentAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/GivenJdoNotPersistentAnnotationFacetFactoryTest.java b/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/GivenJdoNotPersistentAnnotationFacetFactoryTest.java
new file mode 100644
index 0000000..7336b3d
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/GivenJdoNotPersistentAnnotationFacetFactoryTest.java
@@ -0,0 +1,132 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.jdo.annotations.NotPersistent;
+import javax.jdo.annotations.PrimaryKey;
+
+import junit.framework.Assert;
+
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetFactory;
+import org.apache.isis.core.metamodel.facets.mandatory.MandatoryFacet;
+import org.apache.isis.core.metamodel.facets.notpersisted.NotPersistedFacet;
+import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
+import org.apache.isis.core.progmodel.facets.members.disabled.DisabledFacet;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.DisabledFacetDerivedFromJdoPrimaryKeyAnnotation;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.JdoPrimaryKeyFacet;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.OptionalFacetDerivedFromJdoPrimaryKeyAnnotation;
+
+public class GivenJdoNotPersistentAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
+
+    private JdoNotPersistentAnnotationFacetFactory facetFactory;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        facetFactory = new JdoNotPersistentAnnotationFacetFactory();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        facetFactory = null;
+        super.tearDown();
+    }
+
+    public void testFeatureTypes() {
+        final List<FeatureType> featureTypes = facetFactory.getFeatureTypes();
+        assertFalse(contains(featureTypes, FeatureType.OBJECT));
+        assertTrue(contains(featureTypes, FeatureType.PROPERTY));
+        assertFalse(contains(featureTypes, FeatureType.COLLECTION));
+        assertFalse(contains(featureTypes, FeatureType.ACTION));
+        assertFalse(contains(featureTypes, FeatureType.ACTION_PARAMETER));
+    }
+
+    public void testNotPersistentAnnotationPickedUpOnProperty() throws Exception {
+        final Class<?> cls = SimpleObjectWithNotPersistentColumn.class;
+        final Method method = cls.getMethod("getSomeColumn");
+        facetFactory.process(new FacetFactory.ProcessMethodContext(cls, null, null, method, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(JdoNotPersistentFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof JdoNotPersistentFacet);
+    }
+
+    public void testNotPersistedDerived() throws Exception {
+        final Class<?> cls = SimpleObjectWithNotPersistentColumn.class;
+        final Method method = cls.getMethod("getSomeColumn");
+        facetFactory.process(new FacetFactory.ProcessMethodContext(cls, null, null, method, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(NotPersistedFacet.class);
+        assertNotNull(facet);
+        assertTrue(facet instanceof NotPersistedFacetDerivedFromJdoNotPersistentAnnotation);
+    }
+
+    public void testIfNoIdAnnotationThenNoFacet() throws Exception {
+
+        class Customer {
+            private Long someColumn;
+
+            // @NotPersistent missing
+            @SuppressWarnings("unused")
+            public Long getSomeColumn() {
+                return someColumn;
+            }
+
+            @SuppressWarnings("unused")
+            public void setSomeColumn(final Long someColumn) {
+                this.someColumn = someColumn;
+            }
+        }
+
+        final Class<?> cls = Customer.class;
+        final Method method = cls.getMethod("getSomeColumn");
+        facetFactory.process(new FacetFactory.ProcessMethodContext(cls, null, null, method, methodRemover, facetedMethod));
+
+        final Facet facet = facetedMethod.getFacet(JdoNotPersistentFacet.class);
+        assertNull(facet);
+    }
+
+    public void testNoMethodsRemoved() throws Exception {
+        class Customer {
+            private Long someColumn;
+
+            @NotPersistent
+            public Long getSomeColumn() {
+                return someColumn;
+            }
+
+            @SuppressWarnings("unused")
+            public void setSomeColumn(final Long someColumn) {
+                this.someColumn = someColumn;
+            }
+        }
+
+        final Class<?> cls = Customer.class;
+        final Method method = cls.getMethod("getSomeColumn");
+        facetFactory.process(new FacetFactory.ProcessMethodContext(cls, null, null, method, methodRemover, facetedMethod));
+
+        assertNoMethodsRemoved();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/SimpleObjectWithNotPersistentColumn.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/SimpleObjectWithNotPersistentColumn.java b/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/SimpleObjectWithNotPersistentColumn.java
new file mode 100644
index 0000000..0099262
--- /dev/null
+++ b/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/notpersistent/SimpleObjectWithNotPersistentColumn.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent;
+
+import javax.jdo.annotations.NotPersistent;
+
+
+public class SimpleObjectWithNotPersistentColumn {
+
+    private Long someColumn;
+
+    @NotPersistent
+    public Long getSomeColumn() {
+        return someColumn;
+    }
+
+    public void setSomeColumn(final Long someColumn) {
+        this.someColumn = someColumn;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/GivenJdoPrimaryKeyAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/GivenJdoPrimaryKeyAnnotationFacetFactoryTest.java b/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/GivenJdoPrimaryKeyAnnotationFacetFactoryTest.java
index 1693211..180bab7 100644
--- a/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/GivenJdoPrimaryKeyAnnotationFacetFactoryTest.java
+++ b/component/objectstore/jdo/jdo-metamodel/src/test/java/org/apache/isis/objectstore/jdo/metamodel/facets/prop/primarykey/GivenJdoPrimaryKeyAnnotationFacetFactoryTest.java
@@ -51,10 +51,10 @@ public class GivenJdoPrimaryKeyAnnotationFacetFactoryTest extends AbstractFacetF
 
     public void testFeatureTypes() {
         final List<FeatureType> featureTypes = facetFactory.getFeatureTypes();
-        Assert.assertFalse(contains(featureTypes, FeatureType.OBJECT));
+        assertFalse(contains(featureTypes, FeatureType.OBJECT));
         assertTrue(contains(featureTypes, FeatureType.PROPERTY));
         assertFalse(contains(featureTypes, FeatureType.COLLECTION));
-        Assert.assertFalse(contains(featureTypes, FeatureType.ACTION));
+        assertFalse(contains(featureTypes, FeatureType.ACTION));
         assertFalse(contains(featureTypes, FeatureType.ACTION_PARAMETER));
     }
 
@@ -75,7 +75,7 @@ public class GivenJdoPrimaryKeyAnnotationFacetFactoryTest extends AbstractFacetF
 
         final Facet facet = facetedMethod.getFacet(MandatoryFacet.class);
         assertNotNull(facet);
-        Assert.assertTrue(facet instanceof OptionalFacetDerivedFromJdoPrimaryKeyAnnotation);
+        assertTrue(facet instanceof OptionalFacetDerivedFromJdoPrimaryKeyAnnotation);
     }
 
     public void testDisabledDerivedFromId() throws Exception {
@@ -85,7 +85,7 @@ public class GivenJdoPrimaryKeyAnnotationFacetFactoryTest extends AbstractFacetF
 
         final Facet facet = facetedMethod.getFacet(DisabledFacet.class);
         assertNotNull(facet);
-        Assert.assertTrue(facet instanceof DisabledFacetDerivedFromJdoPrimaryKeyAnnotation);
+        assertTrue(facet instanceof DisabledFacetDerivedFromJdoPrimaryKeyAnnotation);
     }
 
     public void testIfNoIdAnnotationThenNoFacet() throws Exception {

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/util/OidUtils.java
----------------------------------------------------------------------
diff --git a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/util/OidUtils.java b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/util/OidUtils.java
index e691865..91f29f0 100644
--- a/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/util/OidUtils.java
+++ b/component/viewer/restfulobjects/server/src/main/java/org/apache/isis/viewer/restfulobjects/server/util/OidUtils.java
@@ -22,7 +22,11 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecId;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
+import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.viewer.restfulobjects.rendering.RendererContext;
 
 public final class OidUtils {
@@ -41,7 +45,6 @@ public final class OidUtils {
     // REVIEW: it's a bit hokey to join these together just to split them out again.
     public static String joinAsOid(final String domainType, final String instanceIdEncoded) {
         final String instanceIdUnencoded = UrlDecoderUtils.urlDecode(instanceIdEncoded);
-        
         return getOidMarshaller().joinAsOid(domainType, instanceIdUnencoded);
     }
 
@@ -62,7 +65,16 @@ public final class OidUtils {
      * @throws {@link ObjectNotFoundException} if not found
      */
     public static ObjectAdapter getObjectAdapterElseThrowNotFound(final RendererContext resourceContext, final String domainType, final String instanceId) throws ObjectNotFoundException {
-        final String oidStr = joinAsOid(domainType, instanceId);
+        String oidStr = joinAsOid(domainType, instanceId);
+        
+        // REVIEW: this is all rather disgusting...
+        final ObjectSpecId specId = ObjectSpecId.of(domainType);
+        final ObjectSpecification spec = IsisContext.getSpecificationLoader().lookupBySpecId(specId);
+        if(spec.containsFacet(ViewModelFacet.class)) {
+            // TODO: use the static in OidMarshaller
+            oidStr = "*" + oidStr;
+        }
+
         return getObjectAdapterForUnencodedElseThrowNotFound(resourceContext, oidStr);
     }
 
@@ -89,7 +101,8 @@ public final class OidUtils {
 
     private static ObjectAdapter getObjectAdapterForUnencodedElseThrowNotFound(final RendererContext resourceContext, final String oidStr) {
         final RootOid rootOid = RootOidDefault.deStringEncoded(oidStr, getOidMarshaller());
-        return resourceContext.getPersistenceSession().loadObject(rootOid);
+        //return resourceContext.getPersistenceSession().loadObject(rootOid);
+        return resourceContext.getPersistenceSession().getAdapterManager().adapterFor(rootOid);
     }
 
     private static OidMarshaller getOidMarshaller() {

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java b/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
new file mode 100644
index 0000000..fe3cb4e
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/AbstractViewModel.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+import org.apache.isis.applib.annotation.ViewModel;
+
+/**
+ * Convenience super class for all view models that wish to interact with the
+ * container.
+ * 
+ * <p>
+ * Subclassing is NOT mandatory; the methods in this superclass can be pushed
+ * down into domain objects and another superclass used if required.
+ * 
+ * @see org.apache.isis.applib.DomainObjectContainer
+ */
+public abstract class AbstractViewModel extends AbstractContainedObject implements ViewModel {
+
+    @Override
+    public abstract String viewModelMemento();
+    
+    @Override
+    public abstract void viewModelInit(final String memento);
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
index 0c06b7f..ebf0751 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
@@ -24,6 +24,7 @@ import java.util.List;
 import com.google.common.base.Predicate;
 
 import org.apache.isis.applib.annotation.Aggregated;
+import org.apache.isis.applib.annotation.ViewModel;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.security.UserMemento;
@@ -160,7 +161,14 @@ public interface DomainObjectContainer {
      * @see #newPersistentInstance(Class)
      * @see #newAggregatedInstance(Object, Class)
      */
-    <T> T newTransientInstance(Class<T> ofType);
+    <T> T newTransientInstance(final Class<T> ofType);
+
+    
+    /**
+     * Create a new instance of the specified {@link ViewModel} class, initializing with the
+     * specified {@link ViewModel#viewModelMemento() memento}.
+     */
+    <T extends ViewModel> T newViewModelInstance(final Class<T> ofType, final String memento);
 
     /**
      * Create a new instance that will be persisted as part of the specified

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
index 3e7777d..26bc81e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/ViewModel.java
@@ -19,21 +19,29 @@
 
 package org.apache.isis.applib.annotation;
 
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 
 /**
- * Indicates that a domain object is intended to be used as a view model,
- * such that any changes to its structure will be backwardly compatible.
- * 
- * <p>
- * Originally introduced to support the json-viewer's RESTful support.
+ * Indicates that a domain object is intended to be used as a view model.
  */
-@Inherited
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-public @interface ViewModel {
+public interface ViewModel {
+
+    /**
+     * Obtain a memento of the view model.
+     *
+     * <p>
+     * Typically this will be the identifier of a backing domain entity, but it could also be an arbitrary string,
+     * for example a bunch of JSON.
+     * 
+     * <p>
+     * This method is called by the framework in order that the view model may be recreated subsequently
+     * through {@link #viewModelInit(String)}.
+     */
+    @Hidden
+    public String viewModelMemento();
+    
+    /**
+     * Used to re-initialize a view model with a memento obtained from {@link #viewModelMemento()}.
+     */
+    @Hidden
+    public void viewModelInit(String memento);
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
index 5e817d3..dec60b6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/DomainObjectServices.java
@@ -40,6 +40,8 @@ public interface DomainObjectServices extends Injectable {
      */
     ObjectAdapter createTransientInstance(ObjectSpecification spec);
 
+    ObjectAdapter createViewModelInstance(ObjectSpecification spec, String memento);
+
     /**
      * Create an instance of an aggregated object that will be persisted within the
      * parent adapter.
@@ -157,4 +159,5 @@ public interface DomainObjectServices extends Injectable {
     List<String> getPropertyNames();
 
 
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/AggregatedOid.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/AggregatedOid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/AggregatedOid.java
index 99337ab..248fd9d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/AggregatedOid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/AggregatedOid.java
@@ -175,14 +175,6 @@ public final class AggregatedOid extends ParentedOid implements TypedOid, Serial
     }
 
 
-    // /////////////////////////////////////////////////////////
-    // toString
-    // /////////////////////////////////////////////////////////
-
-    @Override
-    public String toString() {
-        return enString(new OidMarshaller());
-    }
 
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOid.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOid.java
index 6235ed3..7cb47e3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOid.java
@@ -161,14 +161,5 @@ public final class CollectionOid extends ParentedOid implements Serializable {
 
 
 
-    // /////////////////////////////////////////////////////////
-    // toString
-    // /////////////////////////////////////////////////////////
-
-    @Override
-    public String toString() {
-        return enString(new OidMarshaller());
-    }
-
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
index 1d68d04..dd4501d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
@@ -44,7 +44,8 @@ public interface Oid extends Encodable {
     void setVersion(Version version);
 
     /**
-     * Flags whether this OID is for a transient (not-yet-persisted) object.
+     * Flags whether this OID is for a transient (not-yet-persisted) object, 
+     * or a view model object, or for a persistent object.
      * 
      * <p>
      * In the case of an {@link AggregatedOid}, is determined by the state 
@@ -52,8 +53,14 @@ public interface Oid extends Encodable {
      */
     boolean isTransient();
 
+    boolean isViewModel();
+    
+    boolean isPersistent();
+
     public static enum State {
-        PERSISTENT("P"), TRANSIENT("T");
+        PERSISTENT("P"), 
+        TRANSIENT("T"),
+        VIEWMODEL("V");
         
         private final String code;
         private State(final String code) {
@@ -63,9 +70,11 @@ public interface Oid extends Encodable {
         public boolean isTransient() {
             return this == TRANSIENT;
         }
-
-        public static State valueOf(boolean isTransient) {
-            return isTransient? TRANSIENT: PERSISTENT;
+        public boolean isViewModel() {
+            return this == VIEWMODEL;
+        }
+        public boolean isPersistent() {
+            return this == PERSISTENT;
         }
 
         public String getCode() {

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
index 6ed697b..05d1dc5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshaller.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.core.metamodel.adapter.oid;
 
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
 import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -43,6 +41,8 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
  * <dd>persistent root</dd>
  * <dt>!CUS:123</dt>
  * <dd>transient root</dd>
+ * <dt>*CUS:123</dt>
+ * <dd>view model root</dd>
  * <dt>CUS:123$items</dt>
  * <dd>collection of persistent root</dd>
  * <dt>!CUS:123$items</dt>
@@ -64,6 +64,8 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
  * <dl>
  * <dt>!</dt>
  * <dd>precedes root object type, indicates transient</dd>
+ * <dt>*</dt>
+ * <dd>precedes root object type, indicates transient</dd>
  * <dt>:</dt>
  * <dd>precedes root object identifier</dd>
  * <dt>~</dt>
@@ -80,6 +82,7 @@ import org.apache.isis.core.metamodel.spec.ObjectSpecId;
 public class OidMarshaller {
 
 	private static final String TRANSIENT_INDICATOR = "!";
+    private static final String VIEWMODEL_INDICATOR = "*";
 	private static final String SEPARATOR = ":";
 	private static final String SEPARATOR_NESTING = "~";
 	private static final String SEPARATOR_COLLECTION = "$";
@@ -95,7 +98,7 @@ public class OidMarshaller {
             Pattern.compile(
             		"^(" +
             		   "(" +
-            		     "([" + TRANSIENT_INDICATOR + "])?" +
+            		     "([" + TRANSIENT_INDICATOR + VIEWMODEL_INDICATOR + "])?" +
             		     WORD_GROUP + SEPARATOR + WORD_GROUP + 
             		   ")" +
             		   "(" + 
@@ -143,8 +146,15 @@ public class OidMarshaller {
             throw new IllegalArgumentException("Could not parse OID '" + oidStr + "'; should match pattern: " + OIDSTR_PATTERN.pattern());
         }
 
-        final String isTransientStr = getGroup(matcher, 3);
-        boolean isTransient = TRANSIENT_INDICATOR.equals(isTransientStr);
+        final String isTransientOrViewModelStr = getGroup(matcher, 3);
+        final State state;
+        if("!".equals(isTransientOrViewModelStr)) {
+            state = State.TRANSIENT;
+        } else if("*".equals(isTransientOrViewModelStr)) {
+            state = State.VIEWMODEL;
+        } else {
+            state = State.PERSISTENT;
+        }
         
         final String rootOidStr = getGroup(matcher, 2);
         
@@ -178,7 +188,7 @@ public class OidMarshaller {
         if(collectionName == null) {
             if(aggregateOidParts.isEmpty()) {
                 ensureCorrectType(oidStr, requestedType, RootOidDefault.class); 
-                return (T)new RootOidDefault(ObjectSpecId.of(rootObjectType), rootIdentifier, State.valueOf(isTransient), version);
+                return (T)new RootOidDefault(ObjectSpecId.of(rootObjectType), rootIdentifier, state, version);
             } else {
                 ensureCorrectType(oidStr, requestedType, AggregatedOid.class);
                 final AggregateOidPart lastPart = aggregateOidParts.remove(aggregateOidParts.size()-1);
@@ -246,7 +256,9 @@ public class OidMarshaller {
     }
 
     public final String marshalNoVersion(RootOid rootOid) {
-        return (rootOid.isTransient()? TRANSIENT_INDICATOR : "") + rootOid.getObjectSpecId() + SEPARATOR + rootOid.getIdentifier();
+        final String transientIndicator = rootOid.isTransient()? TRANSIENT_INDICATOR : "";
+        final String viewModelIndicator = rootOid.isViewModel()? VIEWMODEL_INDICATOR : "";
+        return transientIndicator + viewModelIndicator + rootOid.getObjectSpecId() + SEPARATOR + rootOid.getIdentifier();
     }
 
     public final String marshal(CollectionOid collectionOid) {

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java
index fbcf50c..bfa618d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java
@@ -58,7 +58,26 @@ public abstract class ParentedOid implements Oid {
     public boolean isTransient() {
         return getParentOid().isTransient();
     }
+    
+    @Override
+    public boolean isViewModel() {
+        return getParentOid().isViewModel();
+    }
+    
+    @Override
+    public boolean isPersistent() {
+        return getParentOid().isPersistent();
+    }
+
+
+    // /////////////////////////////////////////////////////////
+    // toString
+    // /////////////////////////////////////////////////////////
 
+    @Override
+    public String toString() {
+        return enString(new OidMarshaller());
+    }
 
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefault.java
index 9aa4533..cedc6eb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/RootOidDefault.java
@@ -124,8 +124,8 @@ public final class RootOidDefault implements Serializable, RootOid {
     public RootOidDefault(ObjectSpecId objectSpecId, final String identifier, final State state, Version version) {
         Ensure.ensureThatArg(objectSpecId, is(not(nullValue())));
         Ensure.ensureThatArg(identifier, is(not(nullValue())));
-        Ensure.ensureThatArg(identifier, is(not(IsisMatchers.contains("#"))));
-        Ensure.ensureThatArg(identifier, is(not(IsisMatchers.contains("@"))));
+        Ensure.ensureThatArg(identifier, is(not(IsisMatchers.contains("#"))), "identifier '" + identifier + "' contains a '#' symbol");
+        Ensure.ensureThatArg(identifier, is(not(IsisMatchers.contains("@"))), "identifier '" + identifier + "' contains an '@' symbol");
         Ensure.ensureThatArg(state, is(not(nullValue())));
         
         this.objectSpecId = objectSpecId;
@@ -209,6 +209,16 @@ public final class RootOidDefault implements Serializable, RootOid {
         return state.isTransient();
     }
 
+    @Override
+    public boolean isViewModel() {
+        return state.isViewModel();
+    }
+    
+    @Override
+    public boolean isPersistent() {
+        return state.isPersistent();
+    }
+    
 
     // ////////////////////////////////////////////
     // asPersistent
@@ -294,6 +304,11 @@ public final class RootOidDefault implements Serializable, RootOid {
         return cachedHashCode;
     }
 
+    
+    // /////////////////////////////////////////////////////////
+    // toString
+    // /////////////////////////////////////////////////////////
+
     @Override
     public String toString() {
         return enString(new OidMarshaller());

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
index b7a892a..b4f6cfc 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/viewmodel/ViewModelFacet.java
@@ -31,4 +31,6 @@ import org.apache.isis.core.metamodel.facets.MarkerFacet;
  */
 public interface ViewModelFacet extends MarkerFacet {
 
+    void initialize(Object pojo, String memento);
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
index e979460..bf8dd81 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/runtimecontext/noruntime/RuntimeContextNoRuntime.java
@@ -186,7 +186,12 @@ public class RuntimeContextNoRuntime extends RuntimeContextAbstract {
             public ObjectAdapter createTransientInstance(final ObjectSpecification spec) {
                 throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
             }
-            
+
+            @Override
+            public ObjectAdapter createViewModelInstance(ObjectSpecification spec, String memento) {
+                throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");
+            }
+
             @Override
             public ObjectAdapter createAggregatedInstance(final ObjectSpecification spec, final ObjectAdapter parent) {
                 throw new UnsupportedOperationException("Not supported by this implementation of RuntimeContext");

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
index 6b3f1ee..89b4c25 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/container/DomainObjectContainerDefault.java
@@ -27,6 +27,7 @@ import com.google.common.base.Predicate;
 import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.PersistFailedException;
 import org.apache.isis.applib.RepositoryException;
+import org.apache.isis.applib.annotation.ViewModel;
 import org.apache.isis.applib.filter.Filter;
 import org.apache.isis.applib.filter.Filters;
 import org.apache.isis.applib.query.Query;
@@ -58,6 +59,7 @@ import org.apache.isis.core.metamodel.adapter.oid.AggregatedOid;
 import org.apache.isis.core.metamodel.adapter.util.AdapterUtils;
 import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
 import org.apache.isis.core.metamodel.consent.InteractionResult;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.services.container.query.QueryFindByPattern;
 import org.apache.isis.core.metamodel.services.container.query.QueryFindByTitle;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -105,6 +107,21 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         }
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends ViewModel> T newViewModelInstance(Class<T> ofClass, String memento) {
+        final ObjectSpecification spec = getSpecificationLookup().loadSpecification(ofClass);
+        if (!spec.containsFacet(ViewModelFacet.class)) {
+            throw new IsisException("Type must be a ViewModel: " + ofClass);
+        }
+        final ObjectAdapter adapter = doCreateViewModelInstance(spec, memento);
+        if(adapter.getOid().isViewModel()) {
+            return (T)adapter.getObject();
+        } else {
+            throw new IsisException("Object instantiated but was not given a ViewModel Oid; please report as a possible defect in Isis: " + ofClass);
+        }
+    }
+
     @Override
     @SuppressWarnings("unchecked")
     public <T> T newAggregatedInstance(final Object parent, final Class<T> ofClass) {
@@ -151,6 +168,10 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         return getDomainObjectServices().createTransientInstance(spec);
     }
 
+    protected ObjectAdapter doCreateViewModelInstance(final ObjectSpecification spec, final String memento) {
+        return getDomainObjectServices().createViewModelInstance(spec, memento);
+    }
+
     private ObjectAdapter doCreateAggregatedInstance(final ObjectSpecification spec, final Object parent) {
         final ObjectAdapter parentAdapter = getAdapterManager().getAdapterFor(parent);
         return getDomainObjectServices().createAggregatedInstance(spec, parentAdapter);
@@ -578,6 +599,5 @@ public class  DomainObjectContainerDefault implements DomainObjectContainer, Que
         this.localizationProvider = localizationProvider;
     }
 
-    
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelAnnotationFacetFactory.java
deleted file mode 100644
index 32ad8e5..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelAnnotationFacetFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.progmodel.facets.object.viewmodel.annotation;
-
-import org.apache.isis.applib.annotation.ViewModel;
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facetapi.FacetUtil;
-import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facets.Annotations;
-import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-
-public class ViewModelAnnotationFacetFactory extends FacetFactoryAbstract {
-
-    public ViewModelAnnotationFacetFactory() {
-        super(FeatureType.OBJECTS_ONLY);
-    }
-
-    @Override
-    public void process(final ProcessClassContext processClassContaxt) {
-        final ViewModel annotation = Annotations.getAnnotation(processClassContaxt.getCls(), ViewModel.class);
-        FacetUtil.addFacet(create(annotation, processClassContaxt.getFacetHolder()));
-    }
-
-    private ViewModelFacet create(final ViewModel annotation, final FacetHolder holder) {
-        return annotation == null ? null : new ViewModelFacetAnnotation(holder);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
deleted file mode 100644
index ddae50c..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetAnnotation.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.progmodel.facets.object.viewmodel.annotation;
-
-import org.apache.isis.core.metamodel.facetapi.FacetHolder;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacetAbstract;
-
-public class ViewModelFacetAnnotation extends ViewModelFacetAbstract {
-
-    public ViewModelFacetAnnotation(final FacetHolder holder) {
-        super(holder);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetForInterface.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetForInterface.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetForInterface.java
new file mode 100644
index 0000000..77d9904
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelFacetForInterface.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.progmodel.facets.object.viewmodel.annotation;
+
+import org.apache.isis.applib.annotation.ViewModel;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacetAbstract;
+
+public class ViewModelFacetForInterface extends ViewModelFacetAbstract {
+
+    public ViewModelFacetForInterface(final FacetHolder holder) {
+        super(holder);
+    }
+
+    @Override
+    public void initialize(Object pojo, String memento) {
+        final ViewModel viewModel = (ViewModel)pojo;
+        viewModel.viewModelInit(memento);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelIntefaceFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelIntefaceFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelIntefaceFacetFactory.java
new file mode 100644
index 0000000..f7d6f8b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/object/viewmodel/annotation/ViewModelIntefaceFacetFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.progmodel.facets.object.viewmodel.annotation;
+
+import org.apache.isis.applib.annotation.ViewModel;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facetapi.FeatureType;
+import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+
+public class ViewModelIntefaceFacetFactory extends FacetFactoryAbstract {
+
+    public ViewModelIntefaceFacetFactory() {
+        super(FeatureType.OBJECTS_ONLY);
+    }
+
+    @Override
+    public void process(final ProcessClassContext processClassContaxt) {
+        boolean implementsInterface = ViewModel.class.isAssignableFrom(processClassContaxt.getCls());
+        FacetUtil.addFacet(create(implementsInterface, processClassContaxt.getFacetHolder()));
+    }
+
+    private ViewModelFacet create(final boolean implementsInterface, final FacetHolder holder) {
+        return !implementsInterface ? null : new ViewModelFacetForInterface(holder);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index dae7e1b..ce0f335 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -124,7 +124,7 @@ import org.apache.isis.core.progmodel.facets.object.validate.method.ValidateObje
 import org.apache.isis.core.progmodel.facets.object.validperspec.MustSatisfySpecificationOnTypeFacetFactory;
 import org.apache.isis.core.progmodel.facets.object.validprops.ObjectValidPropertiesFacetFactory;
 import org.apache.isis.core.progmodel.facets.object.value.annotation.ValueFacetFactory;
-import org.apache.isis.core.progmodel.facets.object.viewmodel.annotation.ViewModelAnnotationFacetFactory;
+import org.apache.isis.core.progmodel.facets.object.viewmodel.annotation.ViewModelIntefaceFacetFactory;
 import org.apache.isis.core.progmodel.facets.paged.PagedAnnotationOnCollectionFacetFactory;
 import org.apache.isis.core.progmodel.facets.paged.PagedAnnotationOnTypeFacetFactory;
 import org.apache.isis.core.progmodel.facets.param.autocomplete.ActionParameterAutoCompleteFacetFactory;
@@ -354,7 +354,7 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
 
         addFactory(ImmutableMarkerInterfaceFacetFactory.class);
 
-        addFactory(ViewModelAnnotationFacetFactory.class);
+        addFactory(ViewModelIntefaceFacetFactory.class);
 
         addFactory(MaxLengthAnnotationForTypeFacetFactory.class);
         addFactory(MaxLengthAnnotationForPropertyFacetFactory.class);

http://git-wip-us.apache.org/repos/asf/isis/blob/6ede1ba8/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java b/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java
deleted file mode 100644
index e4a947c..0000000
--- a/core/metamodel/src/test/java/org/apache/isis/core/progmodel/facets/object/stable/ViewModelAnnotationFacetFactoryTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.core.progmodel.facets.object.stable;
-
-import org.apache.isis.applib.annotation.ViewModel;
-import org.apache.isis.core.metamodel.facetapi.Facet;
-import org.apache.isis.core.metamodel.facets.FacetFactory.ProcessClassContext;
-import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
-import org.apache.isis.core.progmodel.facets.AbstractFacetFactoryTest;
-import org.apache.isis.core.progmodel.facets.object.viewmodel.annotation.ViewModelAnnotationFacetFactory;
-import org.apache.isis.core.progmodel.facets.object.viewmodel.annotation.ViewModelFacetAnnotation;
-
-public class ViewModelAnnotationFacetFactoryTest extends AbstractFacetFactoryTest {
-
-    private ViewModelAnnotationFacetFactory facetFactory;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        facetFactory = new ViewModelAnnotationFacetFactory();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        facetFactory = null;
-        super.tearDown();
-    }
-
-    public void testStableAnnotationPickedUpOnClassAndDefaultsToAlways() {
-        @ViewModel
-        class Customer {
-        }
-
-        facetFactory.process(new ProcessClassContext(Customer.class, methodRemover, facetedMethod));
-
-        final Facet facet = facetedMethod.getFacet(ViewModelFacet.class);
-        assertNotNull(facet);
-        assertTrue(facet instanceof ViewModelFacetAnnotation);
-
-        assertNoMethodsRemoved();
-    }
-
-}