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

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new 0f77d2125 CAY-2899 CommitLog: missing lifecycle-induced changes in 
`excludeFromTransaction` mode
0f77d2125 is described below

commit 0f77d2125836e0e6d96cb342e8744975ecff00cf
Author: Nikita Timofeev <[email protected]>
AuthorDate: Wed Oct 22 18:35:25 2025 +0400

    CAY-2899 CommitLog: missing lifecycle-induced changes in 
`excludeFromTransaction` mode
---
 .../cayenne/commitlog/CommitLogModuleExtender.java |  16 +++
 .../commitlog/CommitLogFilter_PreUpdate_IT.java    | 101 ++++++++++++++++++
 .../CommitLogFilter_PreUpdate_OutsideTxIT.java     | 101 ++++++++++++++++++
 .../apache/cayenne/commitlog/db/Auditable5.java    |  30 ++++++
 .../cayenne/commitlog/db/AuditableChild5.java      |  30 ++++++
 .../cayenne/commitlog/db/auto/_Auditable5.java     | 116 +++++++++++++++++++++
 .../commitlog/db/auto/_AuditableChild5.java        | 110 +++++++++++++++++++
 .../commitlog/unit/AuditableRuntimeCase.java       |   9 ++
 .../src/test/resources/lifecycle-map.map.xml       |  27 +++++
 9 files changed, 540 insertions(+)

diff --git 
a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
 
b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
index 39d0b1d7d..a95921984 100644
--- 
a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
+++ 
b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/CommitLogModuleExtender.java
@@ -18,12 +18,14 @@
  ****************************************************************/
 package org.apache.cayenne.commitlog;
 
+import org.apache.cayenne.DataChannelSyncFilter;
 import org.apache.cayenne.commitlog.meta.AnnotationCommitLogEntityFactory;
 import org.apache.cayenne.commitlog.meta.CommitLogEntity;
 import org.apache.cayenne.commitlog.meta.CommitLogEntityFactory;
 import org.apache.cayenne.configuration.runtime.CoreModule;
 import org.apache.cayenne.di.Binder;
 import org.apache.cayenne.di.ListBuilder;
+import org.apache.cayenne.graph.GraphChangeHandler;
 
 /**
  * A builder of a custom extensions module for {@link CommitLogModule} that 
customizes its services and installs
@@ -60,6 +62,7 @@ public class CommitLogModuleExtender {
      * within the transaction, so listeners can commit their code together 
with the main commit.
      */
     public CommitLogModuleExtender excludeFromTransaction() {
+        CoreModule.extend(binder).addSyncFilter(createDiffInitFilter(), true);
         return registerFilter(false);
     }
 
@@ -100,4 +103,17 @@ public class CommitLogModuleExtender {
         }
         return commitLogListeners;
     }
+
+    /**
+     * @return the filter that just initializes incoming Diff
+     */
+    private static DataChannelSyncFilter createDiffInitFilter() {
+        GraphChangeHandler noopHandler = new GraphChangeHandler() {};
+        return (originatingContext, changes, syncType, filterChain)
+                -> {
+            // see ObjectStoreGraphDiff.resolveDiff()
+            changes.apply(noopHandler);
+            return filterChain.onSync(originatingContext, changes, syncType);
+        };
+    }
 }
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_PreUpdate_IT.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_PreUpdate_IT.java
new file mode 100644
index 000000000..5646c4c0d
--- /dev/null
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_PreUpdate_IT.java
@@ -0,0 +1,101 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://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.cayenne.commitlog;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.annotation.PreUpdate;
+import org.apache.cayenne.commitlog.db.AuditLog;
+import org.apache.cayenne.commitlog.db.AuditableChild5;
+import org.apache.cayenne.commitlog.model.ObjectChange;
+import org.apache.cayenne.commitlog.unit.AuditableRuntimeCase;
+import org.apache.cayenne.configuration.runtime.CoreModule;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.runtime.CayenneRuntimeBuilder;
+import org.apache.cayenne.tx.BaseTransaction;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class CommitLogFilter_PreUpdate_IT extends AuditableRuntimeCase {
+
+    protected ObjectContext context;
+    protected CommitLogListener listener;
+
+    @Override
+    protected CayenneRuntimeBuilder configureCayenne() {
+        this.listener = (originatingContext, changes) -> {
+            // assert we are not inside a transaction
+            assertNotNull(BaseTransaction.getThreadTransaction());
+
+            for (ObjectChange c : changes.getUniqueChanges()) {
+                AuditLog log = runtime.newContext().newObject(AuditLog.class);
+                log.setLog("DONE: " + c.getPostCommitId());
+                log.getObjectContext().commitChanges();
+            }
+        };
+
+        return super.configureCayenne()
+                .addModule(binder ->
+                        CoreModule.extend(binder)
+                                .addListenerType(MyPreUpdateListener.class)
+                )
+                .addModule(binder ->
+                        CommitLogModule.extend(binder)
+                                .commitLogAnnotationEntitiesOnly()
+                                .addListener(listener)
+                );
+    }
+
+    @Before
+    public void before() throws Exception {
+        context = runtime.newContext();
+        auditable5.insert(1, "yy");
+        auditableChild5.insert(1, 1, "zz");
+    }
+
+    @Test
+    public void testCommitLog() throws SQLException {
+
+        AuditableChild5 auditableChild = 
ObjectSelect.query(AuditableChild5.class)
+                .selectOne(context);
+        assertEquals("zz", auditableChild.getCharProperty1());
+
+        auditableChild.setCharProperty1("xx");
+
+        context.commitChanges();
+
+        List<Object[]> logs = auditLog.selectAll();
+        assertEquals(2, logs.size());
+    }
+
+    public static class MyPreUpdateListener {
+
+        @PreUpdate({ AuditableChild5.class })
+        public void preUpdate( AuditableChild5 child ) {
+            child.getParent().setCharProperty1("zz");
+        }
+    }
+
+
+}
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_PreUpdate_OutsideTxIT.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_PreUpdate_OutsideTxIT.java
new file mode 100644
index 000000000..ac7d7be80
--- /dev/null
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_PreUpdate_OutsideTxIT.java
@@ -0,0 +1,101 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://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.cayenne.commitlog;
+
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.annotation.PreUpdate;
+import org.apache.cayenne.commitlog.db.AuditLog;
+import org.apache.cayenne.commitlog.db.AuditableChild5;
+import org.apache.cayenne.commitlog.model.ObjectChange;
+import org.apache.cayenne.commitlog.unit.AuditableRuntimeCase;
+import org.apache.cayenne.configuration.runtime.CoreModule;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.runtime.CayenneRuntimeBuilder;
+import org.apache.cayenne.tx.BaseTransaction;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class CommitLogFilter_PreUpdate_OutsideTxIT extends 
AuditableRuntimeCase {
+
+    protected ObjectContext context;
+    protected CommitLogListener listener;
+
+    @Override
+    protected CayenneRuntimeBuilder configureCayenne() {
+        this.listener = (originatingContext, changes) -> {
+            // assert we are not inside a transaction
+            assertNull(BaseTransaction.getThreadTransaction());
+
+            for (ObjectChange c : changes.getUniqueChanges()) {
+                AuditLog log = runtime.newContext().newObject(AuditLog.class);
+                log.setLog("DONE: " + c.getPostCommitId());
+                log.getObjectContext().commitChanges();
+            }
+        };
+
+        return super.configureCayenne()
+                .addModule(binder ->
+                        CoreModule.extend(binder)
+                                .addListenerType(MyPreUpdateListener.class)
+                )
+                .addModule(
+                        b -> CommitLogModule.extend(b)
+                                .commitLogAnnotationEntitiesOnly()
+                                .excludeFromTransaction()
+                                .addListener(listener)
+                );
+    }
+
+    @Before
+    public void before() throws Exception {
+        context = runtime.newContext();
+        auditable5.insert(1, "yy");
+        auditableChild5.insert(1, 1, "zz");
+    }
+
+    @Test
+    public void testCommitLog() throws SQLException {
+
+        AuditableChild5 auditableChild = 
ObjectSelect.query(AuditableChild5.class)
+                .selectOne(context);
+        assertEquals("zz", auditableChild.getCharProperty1());
+
+        auditableChild.setCharProperty1("xx");
+
+        context.commitChanges();
+
+        List<Object[]> logs = auditLog.selectAll();
+        assertEquals(2, logs.size());
+    }
+
+    public static class MyPreUpdateListener {
+
+        @PreUpdate({ AuditableChild5.class })
+        public void preUpdate( AuditableChild5 child ) {
+            child.getParent().setCharProperty1("zz");
+        }
+    }
+
+
+}
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/Auditable5.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/Auditable5.java
new file mode 100644
index 000000000..ed13e0b34
--- /dev/null
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/Auditable5.java
@@ -0,0 +1,30 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://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.cayenne.commitlog.db;
+
+import org.apache.cayenne.commitlog.CommitLog;
+import org.apache.cayenne.commitlog.db.auto._Auditable5;
+
+@CommitLog
+public class Auditable5 extends _Auditable5 {
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/AuditableChild5.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/AuditableChild5.java
new file mode 100644
index 000000000..5e8c44564
--- /dev/null
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/AuditableChild5.java
@@ -0,0 +1,30 @@
+/*****************************************************************
+ *   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
+ *
+ *    https://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.cayenne.commitlog.db;
+
+import org.apache.cayenne.commitlog.CommitLog;
+import org.apache.cayenne.commitlog.db.auto._AuditableChild5;
+
+@CommitLog
+public class AuditableChild5 extends _AuditableChild5 {
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/auto/_Auditable5.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/auto/_Auditable5.java
new file mode 100644
index 000000000..242db2a21
--- /dev/null
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/auto/_Auditable5.java
@@ -0,0 +1,116 @@
+package org.apache.cayenne.commitlog.db.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.List;
+
+import org.apache.cayenne.PersistentObject;
+import org.apache.cayenne.commitlog.db.Auditable5;
+import org.apache.cayenne.commitlog.db.AuditableChild5;
+import org.apache.cayenne.exp.property.ListProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.SelfProperty;
+import org.apache.cayenne.exp.property.StringProperty;
+
+/**
+ * Class _Auditable5 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _Auditable5 extends PersistentObject {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final SelfProperty<Auditable5> SELF = 
PropertyFactory.createSelf(Auditable5.class);
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final StringProperty<String> CHAR_PROPERTY1 = 
PropertyFactory.createString("charProperty1", String.class);
+    public static final ListProperty<AuditableChild5> CHILDREN = 
PropertyFactory.createList("children", AuditableChild5.class);
+
+    protected String charProperty1;
+
+    protected Object children;
+
+    public void setCharProperty1(String charProperty1) {
+        beforePropertyWrite("charProperty1", this.charProperty1, 
charProperty1);
+        this.charProperty1 = charProperty1;
+    }
+
+    public String getCharProperty1() {
+        beforePropertyRead("charProperty1");
+        return this.charProperty1;
+    }
+
+    public void addToChildren(AuditableChild5 obj) {
+        addToManyTarget("children", obj, true);
+    }
+
+    public void removeFromChildren(AuditableChild5 obj) {
+        removeToManyTarget("children", obj, true);
+    }
+
+    @SuppressWarnings("unchecked")
+    public List<AuditableChild5> getChildren() {
+        return (List<AuditableChild5>)readProperty("children");
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "charProperty1":
+                return this.charProperty1;
+            case "children":
+                return this.children;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "charProperty1":
+                this.charProperty1 = (String)val;
+                break;
+            case "children":
+                this.children = val;
+                break;
+            default:
+                super.writePropertyDirectly(propName, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeSerialized(out);
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
+        readSerialized(in);
+    }
+
+    @Override
+    protected void writeState(ObjectOutputStream out) throws IOException {
+        super.writeState(out);
+        out.writeObject(this.charProperty1);
+        out.writeObject(this.children);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
+        super.readState(in);
+        this.charProperty1 = (String)in.readObject();
+        this.children = in.readObject();
+    }
+
+}
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/auto/_AuditableChild5.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/auto/_AuditableChild5.java
new file mode 100644
index 000000000..26e66b211
--- /dev/null
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/db/auto/_AuditableChild5.java
@@ -0,0 +1,110 @@
+package org.apache.cayenne.commitlog.db.auto;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.cayenne.PersistentObject;
+import org.apache.cayenne.commitlog.db.Auditable5;
+import org.apache.cayenne.commitlog.db.AuditableChild5;
+import org.apache.cayenne.exp.property.EntityProperty;
+import org.apache.cayenne.exp.property.PropertyFactory;
+import org.apache.cayenne.exp.property.SelfProperty;
+import org.apache.cayenne.exp.property.StringProperty;
+
+/**
+ * Class _AuditableChild5 was generated by Cayenne.
+ * It is probably a good idea to avoid changing this class manually,
+ * since it may be overwritten next time code is regenerated.
+ * If you need to make any customizations, please use subclass.
+ */
+public abstract class _AuditableChild5 extends PersistentObject {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final SelfProperty<AuditableChild5> SELF = 
PropertyFactory.createSelf(AuditableChild5.class);
+
+    public static final String ID_PK_COLUMN = "ID";
+
+    public static final StringProperty<String> CHAR_PROPERTY1 = 
PropertyFactory.createString("charProperty1", String.class);
+    public static final EntityProperty<Auditable5> PARENT = 
PropertyFactory.createEntity("parent", Auditable5.class);
+
+    protected String charProperty1;
+
+    protected Object parent;
+
+    public void setCharProperty1(String charProperty1) {
+        beforePropertyWrite("charProperty1", this.charProperty1, 
charProperty1);
+        this.charProperty1 = charProperty1;
+    }
+
+    public String getCharProperty1() {
+        beforePropertyRead("charProperty1");
+        return this.charProperty1;
+    }
+
+    public void setParent(Auditable5 parent) {
+        setToOneTarget("parent", parent, true);
+    }
+
+    public Auditable5 getParent() {
+        return (Auditable5)readProperty("parent");
+    }
+
+    @Override
+    public Object readPropertyDirectly(String propName) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch(propName) {
+            case "charProperty1":
+                return this.charProperty1;
+            case "parent":
+                return this.parent;
+            default:
+                return super.readPropertyDirectly(propName);
+        }
+    }
+
+    @Override
+    public void writePropertyDirectly(String propName, Object val) {
+        if(propName == null) {
+            throw new IllegalArgumentException();
+        }
+
+        switch (propName) {
+            case "charProperty1":
+                this.charProperty1 = (String)val;
+                break;
+            case "parent":
+                this.parent = val;
+                break;
+            default:
+                super.writePropertyDirectly(propName, val);
+        }
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        writeSerialized(out);
+    }
+
+    private void readObject(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
+        readSerialized(in);
+    }
+
+    @Override
+    protected void writeState(ObjectOutputStream out) throws IOException {
+        super.writeState(out);
+        out.writeObject(this.charProperty1);
+        out.writeObject(this.parent);
+    }
+
+    @Override
+    protected void readState(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
+        super.readState(in);
+        this.charProperty1 = (String)in.readObject();
+        this.parent = in.readObject();
+    }
+
+}
diff --git 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/unit/AuditableRuntimeCase.java
 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/unit/AuditableRuntimeCase.java
index c86b7e1b7..cbb3e1bff 100644
--- 
a/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/unit/AuditableRuntimeCase.java
+++ 
b/cayenne-commitlog/src/test/java/org/apache/cayenne/commitlog/unit/AuditableRuntimeCase.java
@@ -42,6 +42,9 @@ public abstract class AuditableRuntimeCase {
        protected TableHelper auditable3;
        protected TableHelper auditable4;
 
+       protected TableHelper auditable5;
+       protected TableHelper auditableChild5;
+
        protected TableHelper auditLog;
 
        @Before
@@ -68,6 +71,10 @@ public abstract class AuditableRuntimeCase {
                this.auditable4 = new TableHelper(dbHelper, 
"AUDITABLE4").setColumns("ID", "CHAR_PROPERTY1", "CHAR_PROPERTY2",
                                "AUDITABLE3_ID");
 
+               this.auditable5 = new TableHelper(dbHelper, 
"AUDITABLE5").setColumns("ID", "CHAR_PROPERTY1");
+               this.auditableChild5 = new TableHelper(dbHelper, 
"AUDITABLE_CHILD5").setColumns("ID", "AUDITABLE5_ID",
+                               "CHAR_PROPERTY1");
+
                this.auditableChild1.deleteAll();
                this.auditableChild1x.deleteAll();
                this.auditable1.deleteAll();
@@ -75,6 +82,8 @@ public abstract class AuditableRuntimeCase {
                this.auditable2.deleteAll();
                this.auditable4.deleteAll();
                this.auditable3.deleteAll();
+               this.auditableChild5.deleteAll();
+               this.auditable5.deleteAll();
 
                this.auditLog.deleteAll();
        }
diff --git a/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml 
b/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml
index cbcba1c2f..179bbd8d8 100644
--- a/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml
+++ b/cayenne-commitlog/src/test/resources/lifecycle-map.map.xml
@@ -24,6 +24,10 @@
                <db-attribute name="CHAR_PROPERTY2" type="VARCHAR" 
length="200"/>
                <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
        </db-entity>
+       <db-entity name="AUDITABLE5">
+               <db-attribute name="CHAR_PROPERTY1" type="VARCHAR" 
length="200"/>
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
+       </db-entity>
        <db-entity name="AUDITABLE_CHILD1">
                <db-attribute name="AUDITABLE1_ID" type="INTEGER"/>
                <db-attribute name="CHAR_PROPERTY1" type="VARCHAR" 
length="200"/>
@@ -40,6 +44,11 @@
                <db-attribute name="CHAR_PROPERTY2" type="VARCHAR" 
length="200"/>
                <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
        </db-entity>
+       <db-entity name="AUDITABLE_CHILD5">
+               <db-attribute name="AUDITABLE5_ID" type="INTEGER"/>
+               <db-attribute name="CHAR_PROPERTY1" type="VARCHAR" 
length="200"/>
+               <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
+       </db-entity>
        <db-entity name="AUDIT_LOG">
                <db-attribute name="ID" type="INTEGER" isPrimaryKey="true" 
isMandatory="true"/>
                <db-attribute name="LOG" type="CLOB"/>
@@ -78,6 +87,9 @@
                <obj-attribute name="charProperty1" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY1"/>
                <obj-attribute name="charProperty2" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY2"/>
        </obj-entity>
+       <obj-entity name="Auditable5" 
className="org.apache.cayenne.commitlog.db.Auditable5" 
dbEntityName="AUDITABLE5">
+               <obj-attribute name="charProperty1" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY1"/>
+       </obj-entity>
        <obj-entity name="AuditableChild1" 
className="org.apache.cayenne.commitlog.db.AuditableChild1" 
dbEntityName="AUDITABLE_CHILD1">
                <obj-attribute name="charProperty1" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY1"/>
        </obj-entity>
@@ -88,6 +100,9 @@
                <obj-attribute name="charProperty1" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY1"/>
                <obj-attribute name="charProperty2" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY2"/>
        </obj-entity>
+       <obj-entity name="AuditableChild5" 
className="org.apache.cayenne.commitlog.db.AuditableChild5" 
dbEntityName="AUDITABLE_CHILD5">
+               <obj-attribute name="charProperty1" type="java.lang.String" 
db-attribute-path="CHAR_PROPERTY1"/>
+       </obj-entity>
        <obj-entity name="E1" className="org.apache.cayenne.commitlog.db.E1" 
dbEntityName="E1"/>
        <obj-entity name="E2" className="org.apache.cayenne.commitlog.db.E2" 
dbEntityName="E2"/>
        <obj-entity name="E3" className="org.apache.cayenne.commitlog.db.E3" 
dbEntityName="E3"/>
@@ -107,6 +122,9 @@
        <db-relationship name="auditable3" source="AUDITABLE4" 
target="AUDITABLE3">
                <db-attribute-pair source="AUDITABLE3_ID" target="ID"/>
        </db-relationship>
+       <db-relationship name="children" source="AUDITABLE5" 
target="AUDITABLE_CHILD5" toMany="true">
+               <db-attribute-pair source="ID" target="AUDITABLE5_ID"/>
+       </db-relationship>
        <db-relationship name="parent" source="AUDITABLE_CHILD1" 
target="AUDITABLE1">
                <db-attribute-pair source="AUDITABLE1_ID" target="ID"/>
        </db-relationship>
@@ -116,6 +134,9 @@
        <db-relationship name="parent" source="AUDITABLE_CHILD3" 
target="AUDITABLE2">
                <db-attribute-pair source="AUDITABLE2_ID" target="ID"/>
        </db-relationship>
+       <db-relationship name="parent" source="AUDITABLE_CHILD5" 
target="AUDITABLE5">
+               <db-attribute-pair source="AUDITABLE5_ID" target="ID"/>
+       </db-relationship>
        <db-relationship name="e34s" source="E3" target="E34" 
toDependentPK="true" toMany="true">
                <db-attribute-pair source="ID" target="E3_ID"/>
        </db-relationship>
@@ -132,9 +153,11 @@
        <obj-relationship name="children" source="Auditable2" 
target="AuditableChild3" deleteRule="Deny" db-relationship-path="children"/>
        <obj-relationship name="auditable4s" source="Auditable3" 
target="Auditable4" deleteRule="Deny" db-relationship-path="auditable4s"/>
        <obj-relationship name="auditable3" source="Auditable4" 
target="Auditable3" deleteRule="Nullify" db-relationship-path="auditable3"/>
+       <obj-relationship name="children" source="Auditable5" 
target="AuditableChild5" deleteRule="Deny" db-relationship-path="children"/>
        <obj-relationship name="parent" source="AuditableChild1" 
target="Auditable1" deleteRule="Nullify" db-relationship-path="parent"/>
        <obj-relationship name="parent" source="AuditableChild1x" 
target="Auditable1" deleteRule="Nullify" db-relationship-path="parent"/>
        <obj-relationship name="parent" source="AuditableChild3" 
target="Auditable2" deleteRule="Nullify" db-relationship-path="parent"/>
+       <obj-relationship name="parent" source="AuditableChild5" 
target="Auditable5" deleteRule="Nullify" db-relationship-path="parent"/>
        <obj-relationship name="e4s" source="E3" target="E4" deleteRule="Deny" 
db-relationship-path="e34s.e4"/>
        <obj-relationship name="e3s" source="E4" target="E3" deleteRule="Deny" 
db-relationship-path="e34s.e3"/>
        <cgen xmlns="http://cayenne.apache.org/schema/11/cgen";>
@@ -142,6 +165,10 @@
                <mode>entity</mode>
                <template>templates/v4_1/subclass.vm</template>
                <superTemplate>templates/v4_1/superclass.vm</superTemplate>
+               
<embeddableTemplate>templates/v4_1/embeddable-subclass.vm</embeddableTemplate>
+               
<embeddableSuperTemplate>templates/v4_1/embeddable-superclass.vm</embeddableSuperTemplate>
+               
<queryTemplate>templates/v4_1/datamap-subclass.vm</queryTemplate>
+               
<querySuperTemplate>templates/v4_1/datamap-superclass.vm</querySuperTemplate>
                <outputPattern>*.java</outputPattern>
                <makePairs>true</makePairs>
                <usePkgPath>true</usePkgPath>

Reply via email to