This is an automated email from the ASF dual-hosted git repository. ahuber pushed a commit to branch 3522-dead.end in repository https://gitbox.apache.org/repos/asf/causeway.git
commit ed09506d2227e9713fdd9d178605d70ca6e635bf Author: andi-huber <[email protected]> AuthorDate: Tue Jul 18 13:26:05 2023 +0200 CAUSEWAY-3522: prepare removal of REMOVED state --- .../object/_ManagedObjectEntityHybrid.java | 15 +++--- .../object/_RecognizeObjectDeletedOrNotFound.java | 42 ---------------- .../CausewayModulePersistenceJdoDatanucleus.java | 4 ++ .../exrecog/JdoObjectNotFoundRecognizer.java | 53 ++++++++++++++++++++ .../jdosupport/JdoSupportServiceDefault.java | 3 +- .../metamodel/facets/entity/JdoEntityFacet.java | 14 ++---- .../testdomain/viewers/jpa/wkt/TestAppJpaWkt.java | 3 +- .../testdomain/jdo/entities/JdoBook_delete.java | 57 ++++++++++++++++++++++ .../testdomain/jpa/entities/JpaBook_delete.java | 57 ++++++++++++++++++++++ 9 files changed, 187 insertions(+), 61 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityHybrid.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityHybrid.java index ebf304026f..61dd672ca8 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityHybrid.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_ManagedObjectEntityHybrid.java @@ -20,6 +20,7 @@ package org.apache.causeway.core.metamodel.object; import java.util.Optional; +import org.apache.causeway.applib.exceptions.unrecoverable.ObjectNotFoundException; import org.apache.causeway.applib.services.bookmark.Bookmark; import org.apache.causeway.applib.services.repository.EntityState; import org.apache.causeway.commons.internal.assertions._Assert; @@ -131,16 +132,14 @@ implements _Refetchable { try { val pojo = variant.getPojo(); triggerReassessment(); - return pojo; - } catch (Throwable ex) { - if(_RecognizeObjectDeletedOrNotFound.recognize(ex)) { - // if object not found, transition to 'removed' state - makeRemoved(); - return null; - } + if(pojo==null) makeRemoved(); - throw ex; + return pojo; + } catch (ObjectNotFoundException e) { + // if object not found, transition to 'removed' state + makeRemoved(); + return null; } } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_RecognizeObjectDeletedOrNotFound.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_RecognizeObjectDeletedOrNotFound.java deleted file mode 100644 index 2a5fc7ce7c..0000000000 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/_RecognizeObjectDeletedOrNotFound.java +++ /dev/null @@ -1,42 +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.causeway.core.metamodel.object; - -import org.apache.causeway.commons.internal.exceptions._Exceptions; - -import lombok.NonNull; -import lombok.experimental.UtilityClass; - -@UtilityClass -class _RecognizeObjectDeletedOrNotFound { - - /** - * Returns optionally the {@link Throwable} to throw, based on whether - * the Object-Deleted-Or-Not-Found case could not be detected. - * @return if empty, the Object-Deleted-Or-Not-Found case was detected - */ - boolean recognize(final @NonNull Throwable throwable) { - - return _Exceptions.streamCausalChain(throwable) - .map(Throwable::getClass) - .map(Class::getSimpleName) - .anyMatch(exName->exName.endsWith("ObjectNotFoundException")); - } - -} diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/CausewayModulePersistenceJdoDatanucleus.java b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/CausewayModulePersistenceJdoDatanucleus.java index 5f1bd3f004..0e3d82b1f4 100644 --- a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/CausewayModulePersistenceJdoDatanucleus.java +++ b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/CausewayModulePersistenceJdoDatanucleus.java @@ -47,6 +47,7 @@ import org.apache.causeway.persistence.jdo.datanucleus.changetracking.JdoLifecyc import org.apache.causeway.persistence.jdo.datanucleus.config.DatanucleusSettings; import org.apache.causeway.persistence.jdo.datanucleus.dialect.DnJdoDialect; import org.apache.causeway.persistence.jdo.datanucleus.entities.DnEntityStateProvider; +import org.apache.causeway.persistence.jdo.datanucleus.exrecog.JdoObjectNotFoundRecognizer; import org.apache.causeway.persistence.jdo.datanucleus.jdosupport.JdoSupportServiceDefault; import org.apache.causeway.persistence.jdo.datanucleus.valuetypes.DnByteIdValueSemantics; import org.apache.causeway.persistence.jdo.datanucleus.valuetypes.DnCharIdValueSemantics; @@ -109,12 +110,15 @@ import lombok.extern.log4j.Log4j2; // @Service's JdoSupportServiceDefault.class, + JdoObjectNotFoundRecognizer.class, }) @EnableConfigurationProperties(DatanucleusSettings.class) @Log4j2 public class CausewayModulePersistenceJdoDatanucleus { + public static final String NAMESPACE = "causeway.persistence.jdo"; + /** * Conveniently registers this dialect as a {@link PersistenceExceptionTranslator} with <i>Spring</i>. * @see PersistenceExceptionTranslator diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/exrecog/JdoObjectNotFoundRecognizer.java b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/exrecog/JdoObjectNotFoundRecognizer.java new file mode 100644 index 0000000000..0287dbf3c2 --- /dev/null +++ b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/exrecog/JdoObjectNotFoundRecognizer.java @@ -0,0 +1,53 @@ +/* + * 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.causeway.persistence.jdo.datanucleus.exrecog; + +import java.util.Optional; + +import javax.annotation.Priority; +import javax.inject.Named; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +import org.apache.causeway.applib.annotation.PriorityPrecedence; +import org.apache.causeway.applib.services.exceprecog.Category; +import org.apache.causeway.applib.services.exceprecog.ExceptionRecognizer; +import org.apache.causeway.applib.services.exceprecog.Recognition; +import org.apache.causeway.commons.internal.base._Strings; +import org.apache.causeway.commons.internal.exceptions._Exceptions; +import org.apache.causeway.persistence.jdo.datanucleus.CausewayModulePersistenceJdoDatanucleus; + +@Service +@Named(CausewayModulePersistenceJdoDatanucleus.NAMESPACE + ".JdoObjectNotFoundRecognizer") +@Priority(PriorityPrecedence.MIDPOINT) +@Qualifier("DN6") +public class JdoObjectNotFoundRecognizer implements ExceptionRecognizer { + + @Override + public Optional<Recognition> recognize(final Throwable ex) { + return _Exceptions.streamCausalChain(ex) + .map(Throwable::getClass) + .map(Class::getSimpleName) + .anyMatch(exName->exName.endsWith("ObjectNotFoundException")) + ? Recognition.of(Category.NOT_FOUND, _Strings.nullToEmpty(ex.getMessage())) + : Optional.empty(); + } + +} diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/jdosupport/JdoSupportServiceDefault.java b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/jdosupport/JdoSupportServiceDefault.java index 710369a849..fe1d8c7b90 100644 --- a/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/jdosupport/JdoSupportServiceDefault.java +++ b/persistence/jdo/datanucleus/src/main/java/org/apache/causeway/persistence/jdo/datanucleus/jdosupport/JdoSupportServiceDefault.java @@ -49,12 +49,13 @@ import org.apache.causeway.applib.services.repository.RepositoryService; import org.apache.causeway.commons.internal.collections._Lists; import org.apache.causeway.commons.internal.collections._Maps; import org.apache.causeway.persistence.jdo.applib.services.JdoSupportService; +import org.apache.causeway.persistence.jdo.datanucleus.CausewayModulePersistenceJdoDatanucleus; import org.apache.causeway.persistence.jdo.spring.integration.TransactionAwarePersistenceManagerFactoryProxy; import static org.apache.causeway.commons.internal.base._NullSafe.stream; @Service -@Named("causeway.persistence.jdo.JdoSupportServiceDefault") +@Named(CausewayModulePersistenceJdoDatanucleus.NAMESPACE + ".JdoSupportServiceDefault") @Priority(PriorityPrecedence.MIDPOINT) @Qualifier("DN6") public class JdoSupportServiceDefault implements JdoSupportService { 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 6e09b8a921..fbf9a623d4 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 @@ -34,7 +34,6 @@ import org.datanucleus.enhancement.Persistable; import org.datanucleus.store.rdbms.RDBMSPropertyNames; import org.springframework.lang.Nullable; -import org.apache.causeway.applib.exceptions.unrecoverable.ObjectNotFoundException; import org.apache.causeway.applib.query.AllInstancesQuery; import org.apache.causeway.applib.query.NamedQuery; import org.apache.causeway.applib.query.Query; @@ -187,7 +186,6 @@ implements EntityFacet { log.debug("fetchEntity; bookmark={}", bookmark); - Object entityPojo; try { val persistenceManager = getPersistenceManager(); @@ -195,21 +193,19 @@ implements EntityFacet { val fetchPlan = persistenceManager.getFetchPlan(); fetchPlan.addGroup(FetchGroup.DEFAULT); - entityPojo = persistenceManager.getObjectById(entityClass, primaryKey); + return Optional.ofNullable(persistenceManager.getObjectById(entityClass, primaryKey)); - } catch (final RuntimeException e) { + } catch (final Throwable ex) { - val recognition = exceptionRecognizerService.recognize(e); + val recognition = exceptionRecognizerService.recognize(ex); if(recognition.isPresent()) { if(recognition.get().getCategory() == Category.NOT_FOUND) { - throw new ObjectNotFoundException(""+bookmark, e); + Optional.empty(); // gracefully handle the not found case } } - throw e; + throw ex; } - - return Optional.ofNullable(entityPojo); } @Override diff --git a/regressiontests/stable-viewers-jpa/src/main/java/org/apache/causeway/testdomain/viewers/jpa/wkt/TestAppJpaWkt.java b/regressiontests/stable-viewers-jpa/src/main/java/org/apache/causeway/testdomain/viewers/jpa/wkt/TestAppJpaWkt.java index 6479fbb58d..131f67bf40 100644 --- a/regressiontests/stable-viewers-jpa/src/main/java/org/apache/causeway/testdomain/viewers/jpa/wkt/TestAppJpaWkt.java +++ b/regressiontests/stable-viewers-jpa/src/main/java/org/apache/causeway/testdomain/viewers/jpa/wkt/TestAppJpaWkt.java @@ -34,6 +34,7 @@ import org.apache.causeway.applib.annotation.Nature; import org.apache.causeway.applib.annotation.ObjectSupport; import org.apache.causeway.applib.services.factory.FactoryService; import org.apache.causeway.applib.services.user.UserService; +import org.apache.causeway.commons.internal.debug.xray.XrayEnable; import org.apache.causeway.commons.internal.os._OsUtil; import org.apache.causeway.core.config.presets.CausewayPresets; import org.apache.causeway.testdomain.conf.Configuration_usingJpa; @@ -55,7 +56,7 @@ import org.apache.causeway.viewer.wicket.viewer.CausewayModuleViewerWicketViewer CausewayModuleViewerWicketViewer.class, //CausewayModuleViewerRestfulObjectsJaxrsResteasy.class, - //XrayEnable.class // for debugging only + XrayEnable.class // for debugging only }) public class TestAppJpaWkt extends SpringBootServletInitializer { diff --git a/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/jdo/entities/JdoBook_delete.java b/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/jdo/entities/JdoBook_delete.java new file mode 100644 index 0000000000..f265f54b75 --- /dev/null +++ b/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/jdo/entities/JdoBook_delete.java @@ -0,0 +1,57 @@ +/* + * 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.causeway.testdomain.jdo.entities; + +import java.util.Collection; + +import javax.inject.Inject; + +import org.apache.causeway.applib.annotation.Action; +import org.apache.causeway.applib.annotation.ActionLayout; +import org.apache.causeway.applib.annotation.MemberSupport; +import org.apache.causeway.applib.annotation.SemanticsOf; +import org.apache.causeway.applib.services.repository.RepositoryService; + +import lombok.RequiredArgsConstructor; + +/** + * + * @since 2.0 {@index} + */ +@Action( + semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE +) +@ActionLayout( + associateWith = "name", + position = ActionLayout.Position.PANEL, + sequence = "1" +) +@RequiredArgsConstructor +public class JdoBook_delete { + + @Inject private RepositoryService repository; + + private final JdoBook holder; + + @MemberSupport public Collection<JdoBook> act() { + repository.remove(holder); + return repository.allInstances(JdoBook.class); + } + +} diff --git a/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/jpa/entities/JpaBook_delete.java b/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/jpa/entities/JpaBook_delete.java new file mode 100644 index 0000000000..bd1c64441e --- /dev/null +++ b/regressiontests/stable/src/main/java/org/apache/causeway/testdomain/jpa/entities/JpaBook_delete.java @@ -0,0 +1,57 @@ +/* + * 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.causeway.testdomain.jpa.entities; + +import java.util.Collection; + +import javax.inject.Inject; + +import org.apache.causeway.applib.annotation.Action; +import org.apache.causeway.applib.annotation.ActionLayout; +import org.apache.causeway.applib.annotation.MemberSupport; +import org.apache.causeway.applib.annotation.SemanticsOf; +import org.apache.causeway.applib.services.repository.RepositoryService; + +import lombok.RequiredArgsConstructor; + +/** + * + * @since 2.0 {@index} + */ +@Action( + semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE +) +@ActionLayout( + associateWith = "name", + position = ActionLayout.Position.PANEL, + sequence = "1" +) +@RequiredArgsConstructor +public class JpaBook_delete { + + @Inject private RepositoryService repository; + + private final JpaBook holder; + + @MemberSupport public Collection<JpaBook> act() { + repository.remove(holder); + return repository.allInstances(JpaBook.class); + } + +}
