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

danhaywood pushed a commit to branch CAUSEWAY-3899
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 385ff1462a95cf5fac3f1a364d8758310da58033
Author: Dan Haywood <[email protected]>
AuthorDate: Tue Jul 22 11:26:26 2025 +0100

    CAUSEWAY-3899: adds guard for DomainChangeRecord
---
 .../applib/mixins/system/DomainChangeRecord.java   | 21 ++++++++++--
 .../mixins/system/DomainChangeRecord_Test.java     | 37 ++++++++++++++++++++++
 2 files changed, 55 insertions(+), 3 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord.java
index b01d8189c2b..a39cdc85561 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord.java
@@ -21,6 +21,7 @@
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Optional;
 import java.util.UUID;
 
 import org.apache.causeway.applib.annotation.DomainObject;
@@ -161,8 +162,8 @@ public String toString() {
     @Retention(RetentionPolicy.RUNTIME)
     @interface TargetLogicalTypeName {
         int MAX_LENGTH = 255;
-        boolean NULLABLE = false;
-        String ALLOWS_NULL = "false";
+        boolean NULLABLE = HasTarget.Target.NULLABLE;
+        String ALLOWS_NULL = HasTarget.Target.ALLOWS_NULL;
     }
 
     /**
@@ -170,7 +171,9 @@ public String toString() {
      */
     @TargetLogicalTypeName
     default String getTargetLogicalTypeName() {
-        return getTarget().getLogicalTypeName();
+        return Optional.ofNullable(getTarget())
+                .map(Bookmark::getLogicalTypeName)
+                .orElse(null);
     }
 
 
@@ -332,4 +335,16 @@ default boolean hidePostValue() {
         return getType() != ChangeType.AUDIT_ENTRY;
     }
 
+    /**
+     * A no-op implementation of {@link DomainChangeRecord} that can be used 
for testing.
+     */
+    class Empty implements DomainChangeRecord {
+        @Override public ChangeType getType() {return null;}
+        @Override public UUID getInteractionId() {return null;}
+        @Override public String getUsername() {return "";}
+        @Override public java.sql.Timestamp getTimestamp() {return null;}
+        @Override public Bookmark getTarget() {return null;}
+        @Override public String getLogicalMemberIdentifier() {return "";}
+    }
+
 }
diff --git 
a/api/applib/src/test/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord_Test.java
 
b/api/applib/src/test/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord_Test.java
new file mode 100644
index 00000000000..dbcd263d8e0
--- /dev/null
+++ 
b/api/applib/src/test/java/org/apache/causeway/applib/mixins/system/DomainChangeRecord_Test.java
@@ -0,0 +1,37 @@
+package org.apache.causeway.applib.mixins.system;
+
+import java.util.UUID;
+
+import org.apache.causeway.applib.services.bookmark.Bookmark;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DomainChangeRecord_Test {
+
+    @Test
+    void when_populated() {
+        final var dcr = new DomainChangeRecord.Empty() {
+            @Override
+            public Bookmark getTarget() {
+                return Bookmark.forLogicalTypeNameAndIdentifier("Customer", 
"12345");
+            }
+        };
+
+        assertThat(dcr.getTargetLogicalTypeName()).isEqualTo("Customer");
+    }
+
+    @Test
+    void when_not_populated() {
+        final var dcr = new DomainChangeRecord.Empty() {
+            @Override
+            public Bookmark getTarget() {
+                return null;
+            }
+        };
+
+        assertThat(dcr.getTargetLogicalTypeName()).isNull();
+    }
+
+}
\ No newline at end of file

Reply via email to