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 {
