This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 57ed655e0fbef810b174bd069d28797489364f52
Author: Andi Huber <[email protected]>
AuthorDate: Wed Sep 14 12:11:57 2022 +0200

    ISIS-3208: transient entities, might need a tx-flush, so we get an OID
---
 .../isis/core/metamodel/object/MmEntityUtil.java       | 18 ++++++++++++++++++
 .../executor/MemberExecutorServiceDefault.java         |  6 ++++++
 .../jpa/integration/entity/JpaEntityFacet.java         |  5 ++++-
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
index c3cbcf2294..b4da60d7e2 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/object/MmEntityUtil.java
@@ -82,6 +82,24 @@ public final class MmEntityUtil {
         }
     }
 
+    /**
+     * Handles transient entities that have no OID yet, but get one once the 
current transaction flushes.
+     * As a side-effect transitions a transient entity to a bookmarked one. 
For bookmarked entities,
+     * or any non-entity types acts as a no-op.
+     */
+    public static void ifHasNoOidThenFlush(final @Nullable ManagedObject 
entity) {
+        if(ManagedObjects.isNullOrUnspecifiedOrEmpty(entity)
+                || !entity.getSpecialization().isEntity()
+                || entity.isBookmarkMemoized()) {
+            return;
+        }
+        if(!hasOid(entity)) {
+            entity.getTransactionService().flushTransaction();
+            // force reassessment: as a side-effect transitions the transient 
entity to a bookmarked one
+            entity.getEntityState();
+        }
+    }
+
     /**
      * @param managedObject
      * @return managedObject
diff --git 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index 4d3606e525..2ea749f9e5 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -56,6 +56,7 @@ import 
org.apache.isis.core.metamodel.facets.properties.property.modify.Property
 import org.apache.isis.core.metamodel.interactions.InteractionHead;
 import org.apache.isis.core.metamodel.object.ManagedObject;
 import org.apache.isis.core.metamodel.object.ManagedObjects;
+import org.apache.isis.core.metamodel.object.MmEntityUtil;
 import org.apache.isis.core.metamodel.object.MmUnwrapUtil;
 import org.apache.isis.core.metamodel.object.MmVisibilityUtil;
 import org.apache.isis.core.metamodel.object.PackedManagedObject;
@@ -166,6 +167,11 @@ implements MemberExecutorService {
         // assert has bookmark, unless non-scalar
         ManagedObjects.asScalarNonEmpty(returnedAdapter)
         .filter(scalarNonEmpty->!scalarNonEmpty.getSpecialization().isOther()) 
// don't care
+        // if its a transient entity, flush the current transaction, so we get 
an OID
+        .filter(scalarNonEmpty->{
+            MmEntityUtil.ifHasNoOidThenFlush(scalarNonEmpty);
+            return true;
+        })
         .ifPresent(scalarNonEmpty->{
             _Assert.assertTrue(scalarNonEmpty.getBookmark().isPresent(), 
()->String.format(
                     "bookmark required for non-empty scalars %s", 
scalarNonEmpty.getSpecification()));
diff --git 
a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
 
b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
index 6b4d3b6593..3767849c6d 100644
--- 
a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
+++ 
b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacet.java
@@ -253,13 +253,16 @@ public class JpaEntityFacet
         }
 
         val entityManager = getEntityManager();
+        val primaryKey = 
getPersistenceUnitUtil(entityManager).getIdentifier(pojo);
 
         if (entityManager.contains(pojo)) {
+            if (primaryKey == null) {
+                return EntityState.PERSISTABLE_ATTACHED_NO_OID;
+            }
             return EntityState.PERSISTABLE_ATTACHED;
         }
 
         try {
-            val primaryKey = 
getPersistenceUnitUtil(entityManager).getIdentifier(pojo);
             if (primaryKey == null) {
                 return EntityState.PERSISTABLE_DETACHED;
             } else {

Reply via email to