[ https://issues.apache.org/jira/browse/CAUSEWAY-3688?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Daniel Keir Haywood resolved CAUSEWAY-3688. ------------------------------------------- Resolution: Fixed > Audit trail should gracefully _attempt_ to capture values, but not fail fast. > ----------------------------------------------------------------------------- > > Key: CAUSEWAY-3688 > URL: https://issues.apache.org/jira/browse/CAUSEWAY-3688 > Project: Causeway > Issue Type: Improvement > Components: Ext Sec AuditTrail > Affects Versions: 2.0.0-RC4 > Reporter: Daniel Keir Haywood > Assignee: Daniel Keir Haywood > Priority: Major > Fix For: 2.0.0-RC5 > > > In Estatio, we have: > `LeaseContractFra` -> `LeaseContractFraCustomData`. On the former: > {code:java} > @Programmatic > public CustomContractDataFra getCustomContractDataFra() { > if (leaseContractRepository == null) return null; // for unit testing > return > leaseContractRepository.findCustomContractFraData(this).orElse(null); > } {code} > There's also a derived property 'getConditionPrecedentComment' on the > LeaseContractFra which exposes one of the properties of the associated > LeaseContractFraCustomData: > > {code:java} > @PropertyLayout(multiLine = 5) > public String getConditionPrecedentComment() { > return getCustomContractDataFra().getConditionPrecedentComment(); > } {code} > > Now the `LeaseContractFra` is the aggregate root ... when it is deleted it > cascades the delete of the `LeaseContractFraCustomData` first, and then > itself: > {code:java} > @Action(semantics = SemanticsOf.NON_IDEMPOTENT_ARE_YOU_SURE, domainEvent = > RemoveEvent.class) > public void remove() { > if (getCustomContractDataFra() != null) { > repositoryService.removeAndFlush(getCustomContractDataFra()); > } > // ... > repositoryService.removeAndFlush(this); > } {code} > > # n the the audit trail component is called via the JDO "preDelete" callback > of `LeaseContractFra`, it iterates over all of the properties of said object, > including the derived `getConditionPrecedentComment`, and then NPEs. > Options: > # put the burden of responsibility with the developer, either by > ## exclude this derived property from the audit trail using > `@Property(entityChangePublishing = DISABLED), or > ## adding a null guard in the body of the derived property > # change the audit trail to automatically ignore derived properties on the > basis that they are after all derived and the audit trail will have captured > the values of the underlying data that they are based upon. (This is true in > theory, but in practice figuring out the value of that derived property could > be non-trivial; if nothing else, it makes the audit trail less valuable). > # change the audit trail into a "best effort", ie it _attempts_ to read the > value of the property, but if it fails then it just continues. In other > words, this is a soft failure, similar to how if a `title()` method fails, > then we render "Failed Title" but otherwise continue. > Recommendation: let's go with option #3 -- This message was sent by Atlassian Jira (v8.20.10#820010)