You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/06/24 06:42:52 UTC
[causeway] branch 3500-entity.state.cleanup created (now 3c5e27797a)
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a change to branch 3500-entity.state.cleanup
in repository https://gitbox.apache.org/repos/asf/causeway.git
at 3c5e27797a CAUSEWAY-3500: first iteration, renaming with no behavioral changes
This branch includes the following new commits:
new 3c5e27797a CAUSEWAY-3500: first iteration, renaming with no behavioral changes
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[causeway] 01/01: CAUSEWAY-3500: first iteration, renaming with no behavioral changes
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 3500-entity.state.cleanup
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 3c5e27797a2565fb81783c5cf09f9de2c9dc19c6
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jun 24 08:42:46 2023 +0200
CAUSEWAY-3500: first iteration, renaming with no behavioral changes
---
.../applib/services/repository/EntityState.java | 87 ++++++++++++++--------
.../value/semantics/TemporalValueSemantics.java | 2 +-
.../core/metamodel/object/MmEntityUtils.java | 7 +-
.../object/_ManagedObjectEntityBookmarked.java | 2 +-
.../param/ChoicesAndDefaultsPostProcessor.java | 1 -
.../executor/MemberExecutorServiceDefault.java | 5 +-
.../entities/DnEntityStateProvider.java | 2 +-
.../metamodel/facets/entity/JdoEntityFacet.java | 3 +-
.../jpa/integration/entity/JpaEntityFacet.java | 10 +--
.../JpaGeneratedLongIdEntityLifecycleTest.java | 4 +-
...JpaNonGeneratedStringIdEntityLifecycleTest.java | 4 +-
11 files changed, 76 insertions(+), 51 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/services/repository/EntityState.java b/api/applib/src/main/java/org/apache/causeway/applib/services/repository/EntityState.java
index 861ca4aca6..c374c1a1ae 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/services/repository/EntityState.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/services/repository/EntityState.java
@@ -39,76 +39,105 @@ public enum EntityState {
*/
PERSISTABLE_ATTACHED,
/**
- * Object with this state is an entity but that is detached from a
- * persistence session, in other words changes to the entity will <i>not</i>
- * be flushed back to the database.
- *
- * <h1>JDO specifics:</h1>
+ * Is attached, has no OID yet. On pre-store.
+ */
+ PERSISTABLE_ATTACHED_NO_OID,
+ /**
+ * <h1>JDO specific</h1>
+ * Object with this state is an entity that is detached from a
+ * persistence session and cannot be re-attached,
+ * in other words changes to the entity will <i>not</i>
+ * be tracked nor flushed back to the database.
* <p>
- * JDO distinguishes between DETACHED and HOLLOW, where we are using HOLLOW here,
+ * JDO distinguishes between DETACHED and HOLLOW,
* by virtue of {@code datanucleus.detachAllOnCommit=false}.
* <p>
- * (Unfortunately, we have not found a way to recover <i>OIDs</i> from <i>hollow</i> entities,
- * as used for serialization post commit. So a workaround is in place with DnStateManagerForHollow.)
+ * To recover <i>OIDs</i> from <i>hollow</i> entities, we introduced the DnStateManagerForHollow.
*
* @see "https://www.datanucleus.org/products/accessplatform_6_0/jdo/persistence.html#lifecycle"
*/
+ PERSISTABLE_HOLLOW,
+ /**
+ * Is detached (has an OID). Supports re-attachment.
+ * <p>
+ * That is,
+ * when after a commit the entity had become DETACHED, it can be used elsewhere in the application.
+ * You then attach any changes back to persistence and it becomes ATTACHED again.
+ * <p>
+ * Supported by JDO and JPA. However, at the time of writing, we don't make use of this technology,
+ * but instead re-fetch entities based on their OID.
+ */
PERSISTABLE_DETACHED,
+
+ PERSISTABLE_DETACHED_NO_OID,
/**
* Object with this state is an entity that has been removed from the
* database. Objects in this state may no longer be interacted with.
*/
PERSISTABLE_REMOVED,
- /**
- * Is attached, has no OID yet. On pre-store.
- */
- PERSISTABLE_ATTACHED_NO_OID,
- /**
- * JPA specific. Is detached, but has an OID.
- */
- PERSISTABLE_DETACHED_WITH_OID,
-
;
/**
- * Object is an entity so is <i>potentially</i> persistable ot the database.
+ * Object is an entity so is <i>potentially</i> persistable to the database.
*/
public boolean isPersistable() { return this != NOT_PERSISTABLE; }
/**
* Object with this state is an entity that is attached to a persistence
* session, in other words changes to the entity will be flushed back to
* the database.
+ * @see #PERSISTABLE_ATTACHED
*/
public boolean isAttached() { return this == PERSISTABLE_ATTACHED; }
/**
* Object with this state is an entity but that is detached from a
- * persistence session, in other words changes to the entity will <i>not</i>
+ * persistence session and cannot be re-attached,
+ * in other words changes to the entity will <i>not</i>
* be flushed back to the database.
+ * @see #PERSISTABLE_HOLLOW
+ */
+ //TODO[CAUSEWAY-3500] perhaps reflect the fact, that this is JDO only with a better name
+ public boolean isHollow() { return this == PERSISTABLE_HOLLOW; }
+
+ /**
+ * Is detached and has an OID.
*/
- public boolean isDetached() { return this == PERSISTABLE_DETACHED; }
+ public boolean isDetachedWithOid() { return this == PERSISTABLE_DETACHED; }
+
+ /**
+ * Is detached but has <b>no</b> OID.
+ */
+ //TODO[CAUSEWAY-3500] potential misnomer: detached per def. has an OID
+ public boolean isDetachedNoOid() { return this == PERSISTABLE_DETACHED_NO_OID; }
+
/**
* Object with this state is an entity that has been removed from the
* database. Objects in this state may no longer be interacted with.
* <p>
* Only supported by JDO. Will always return false with JPA.
+ * @see #PERSISTABLE_REMOVED
*/
+ //TODO[CAUSEWAY-3500] perhaps reflect the fact, that this is JDO only with a better name
public boolean isRemoved() { return this == PERSISTABLE_REMOVED; }
// -- SPECIAL STATES
/**
- * @apiNote Is attached, has no OID yet. (On pre-store.)
+ * Is attached, has no OID yet. (On pre-store.)
*/
public boolean isAttachedNoOid() {
return this == PERSISTABLE_ATTACHED_NO_OID;
}
+ //TODO[CAUSEWAY-3500] potential misnomer: if detached per def has an OID
+ //FIXME[CAUSEWAY-3500] in fact hollow can now be re-attached
public boolean isDetachedCannotReattach() {
- return (isDetached()
+ return (isHollow()
+ || isDetachedNoOid()
|| isRemoved())
- && !isJpaSpecificDetachedWithOid();
+ && !isDetachedWithOid();
}
+ //TODO[CAUSEWAY-3500] either remove or un-deprecate
/**
* @apiNote 'removed' is only supported by JDO.
* @deprecated not supported by JPA
@@ -119,19 +148,11 @@ public enum EntityState {
|| isRemoved();
}
- // -- JPA SPECIFIC STATES
-
- /**
- * @apiNote JPA specific. Is detached, but has an OID.
- */
- public boolean isJpaSpecificDetachedWithOid() {
- return this == PERSISTABLE_DETACHED_WITH_OID;
- }
-
// -- BOOKMARKABLE
+ //TODO[CAUSEWAY-3500] in fact hollow potentially also has an OID now
public boolean hasOid() {
- return isAttached() || isJpaSpecificDetachedWithOid();
+ return isAttached() || isDetachedWithOid();
}
}
diff --git a/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java b/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
index 63b147a411..9e42fe869d 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/value/semantics/TemporalValueSemantics.java
@@ -223,7 +223,7 @@ extends
* @apiNote Yet only tested with {@literal XXX}, as there needs to be a format correspondence with
* <i>momentJs</i> for the <i>tempus-dominus</i> date/time-picker to work
* (as used by the <i>Wicket Viewer</i>).
- * {@link org.apache.causeway.viewer.wicket.ui.components.scalars.datepicker._TimeFormatUtil}
+ * {@link org.apache.causeway.viewer.wicket.ui.components.pops.datepicker._TimeFormatUtil}
* does the format conversion.
*/
@NonNull //@NotEmpty
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtils.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtils.java
index 677873e1fa..24d5f7a238 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtils.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmEntityUtils.java
@@ -191,16 +191,19 @@ public final class MmEntityUtils {
return MmEntityUtils.getEntityState(adapter).hasOid();
}
+ //TODO[CAUSEWAY-3500] potential misnomer: if detached per def has an OID
public boolean isDetachedCannotReattach(final @Nullable ManagedObject adapter) {
return MmEntityUtils.getEntityState(adapter).isDetachedCannotReattach();
}
+ //FIXME[CAUSEWAY-3500]
/** TODO very strange logic */
public boolean isDeleted(final @Nullable ManagedObject entity) {
val state = MmEntityUtils.getEntityState(entity);
- return state.isDetached()
+ return state.isHollow()
+ || state.isDetachedNoOid()
|| state.isRemoved()
- || state.isJpaSpecificDetachedWithOid();
+ || state.isDetachedWithOid();
}
}
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
index 962a5ccf6f..fa6681873e 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityBookmarked.java
@@ -121,7 +121,7 @@ implements _Refetchable {
if(refetchedIfSuccess.isEmpty()) {
// if cannot refetch from this special JPA state, try again later
- if(entityState.isJpaSpecificDetachedWithOid()) {
+ if(entityState.isDetachedWithOid()) {
return pojo;
}
// eg. throws on deleted entity
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
index 39b1e6ad15..23cbfc291e 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/postprocessors/param/ChoicesAndDefaultsPostProcessor.java
@@ -24,7 +24,6 @@ import org.apache.causeway.applib.annotation.Where;
import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.facetapi.FacetUtil;
-import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet;
import org.apache.causeway.core.metamodel.facets.object.defaults.DefaultedFacet;
import org.apache.causeway.core.metamodel.facets.objectvalue.choices.ChoicesFacet;
import org.apache.causeway.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
diff --git a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
index e8b43bb7de..e6b3dabbe0 100644
--- a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/executor/MemberExecutorServiceDefault.java
@@ -309,8 +309,9 @@ implements MemberExecutorService {
if(!entityState.isPersistable()) {
return;
}
- if(entityState.isDetached()
- || entityState.isJpaSpecificDetachedWithOid()) {
+ if(entityState.isHollow()
+ || entityState.isDetachedNoOid()
+ || entityState.isDetachedWithOid()) {
// ensure that any still-to-be-persisted adapters get persisted to DB.
getTransactionService().flushTransaction();
}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
index e8853bf509..a495261e67 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/entities/DnEntityStateProvider.java
@@ -79,7 +79,7 @@ public class DnEntityStateProvider implements JdoFacetContext {
? EntityState.PERSISTABLE_ATTACHED
: EntityState.PERSISTABLE_ATTACHED_NO_OID;
}
- return EntityState.PERSISTABLE_DETACHED;
+ return EntityState.PERSISTABLE_HOLLOW;
}
// -- HELPER
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
index 27b60d0f6f..1338d2435d 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
@@ -145,11 +145,12 @@ implements EntityFacet {
val entityState = getEntityState(pojo);
+ //TODO[CAUSEWAY-3500] could be refactored such that the HOLLOW state has on OID and provides it via the HollowStateManager
if (!entityState.hasOid()) {
/* for previously attached objects that have become hollow,
* the OID can be looked up in our pseudo StateManager,
* that only acts as a holder of OID. */
- return entityState.isDetached()
+ return entityState.isHollow()
? DnOidStoreAndRecoverHelper.forEntity((Persistable)pojo).recoverOid()
: Optional.empty();
}
diff --git a/persistence/jpa/integration/src/main/java/org/apache/causeway/persistence/jpa/integration/entity/JpaEntityFacet.java b/persistence/jpa/integration/src/main/java/org/apache/causeway/persistence/jpa/integration/entity/JpaEntityFacet.java
index 82cfb7ea22..5bbbc0811d 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/causeway/persistence/jpa/integration/entity/JpaEntityFacet.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/causeway/persistence/jpa/integration/entity/JpaEntityFacet.java
@@ -252,13 +252,13 @@ public class JpaEntityFacet
try {
val primaryKey = persistenceUnitUtil.getIdentifier(pojo);
if (primaryKey == null) {
- return EntityState.PERSISTABLE_DETACHED;
+ return EntityState.PERSISTABLE_DETACHED_NO_OID;
} else {
// detect shallow primary key
//TODO this is a hack - see whether we can actually ask the EntityManager to give us an accurate answer
return primaryKeyType.isValid(primaryKey)
- ? EntityState.PERSISTABLE_DETACHED_WITH_OID
- : EntityState.PERSISTABLE_DETACHED;
+ ? EntityState.PERSISTABLE_DETACHED
+ : EntityState.PERSISTABLE_DETACHED_NO_OID;
}
} catch (PersistenceException ex) {
/* horrible hack, but encountered NPEs if using a composite key (eg CommandLogEntry)
@@ -268,12 +268,12 @@ public class JpaEntityFacet
DescriptorException descriptorException = (DescriptorException) cause;
Throwable internalException = descriptorException.getInternalException();
if (internalException instanceof NullPointerException) {
- return EntityState.PERSISTABLE_DETACHED;
+ return EntityState.PERSISTABLE_DETACHED_NO_OID;
}
}
if (cause instanceof NullPointerException) {
// horrible hack, encountered if using composite key (eg ExecutionLogEntry) with dynamic weaving
- return EntityState.PERSISTABLE_DETACHED;
+ return EntityState.PERSISTABLE_DETACHED_NO_OID;
}
throw ex;
}
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaGeneratedLongIdEntityLifecycleTest.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaGeneratedLongIdEntityLifecycleTest.java
index b8280ee2b6..8cd159bfef 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaGeneratedLongIdEntityLifecycleTest.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaGeneratedLongIdEntityLifecycleTest.java
@@ -77,7 +77,7 @@ class JpaGeneratedLongIdEntityLifecycleTest {
assertTrue(entity.getSpecification().isEntity());
assertEquals(
- EntityState.PERSISTABLE_DETACHED,
+ EntityState.PERSISTABLE_DETACHED_NO_OID,
MmEntityUtils.getEntityState(entity));
setEntityRef(entity);
@@ -103,7 +103,7 @@ class JpaGeneratedLongIdEntityLifecycleTest {
// expected post-condition (after persist, and having entered a new transaction)
assertEquals(
- EntityState.PERSISTABLE_DETACHED_WITH_OID,
+ EntityState.PERSISTABLE_DETACHED,
MmEntityUtils.getEntityState(getEntityRef()));
val id = ((JpaEntityGeneratedLongId)getEntityRef().getPojo()).getId();
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java
index 3f585ef077..1964d0622b 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/causeway/testdomain/persistence/jpa/entitylifecycle/JpaNonGeneratedStringIdEntityLifecycleTest.java
@@ -77,7 +77,7 @@ class JpaNonGeneratedStringIdEntityLifecycleTest {
assertTrue(entity.getSpecification().isEntity());
assertEquals(
- EntityState.PERSISTABLE_DETACHED_WITH_OID,
+ EntityState.PERSISTABLE_DETACHED,
MmEntityUtils.getEntityState(entity));
setEntityRef(entity);
@@ -102,7 +102,7 @@ class JpaNonGeneratedStringIdEntityLifecycleTest {
// expected post-condition (after persist, and having entered a new transaction)
assertEquals(
- EntityState.PERSISTABLE_DETACHED_WITH_OID,
+ EntityState.PERSISTABLE_DETACHED,
MmEntityUtils.getEntityState(getEntityRef()));
val id = ((JpaEntityNonGeneratedStringId)getEntityRef().getPojo()).getName();