This is an automated email from the ASF dual-hosted git repository. ntimofeev pushed a commit to branch STABLE-4.2 in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit cc51de1baecc1e67e08206a9603d8618cb91aecd Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Thu Feb 29 13:08:16 2024 +0400 CAY-2838 Vertical Inheritance: Problem setting db attribute to null via flattened path --- .../access/flush/ArcValuesCreationHandler.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java index 1ca012aa6..560ab7bfa 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/flush/ArcValuesCreationHandler.java @@ -119,7 +119,7 @@ class ArcValuesCreationHandler implements GraphChangeHandler { // if ID is present, just use it, otherwise create new String flattenedPath = path.toString(); - // if this is last segment and it's a relationship, use known target id from arc creation + // if this is the last segment, and it's a relationship, use known target id from arc creation if(!dbPathIterator.hasNext()) { targetId = finalTargetId; } else { @@ -151,8 +151,7 @@ class ArcValuesCreationHandler implements GraphChangeHandler { // should update existing DB row factory.getOrCreate(target, targetId, add ? DbRowOpType.UPDATE : defaultType); } - // should always add data from the intermediate relationship - processRelationship(relationship, srcId, targetId, dbPathIterator.hasNext() || add); + processRelationship(relationship, srcId, targetId, shouldProcessAsAddition(relationship, add)); srcId = targetId; // use target as next source } } @@ -160,6 +159,20 @@ class ArcValuesCreationHandler implements GraphChangeHandler { return targetId; } + private boolean shouldProcessAsAddition(DbRelationship relationship, boolean add) { + if(add) { + return true; + } + + // should always add data from one-to-one relationships + for(DbJoin join : relationship.getJoins()) { + if(!join.getSource().isPrimaryKey() || !join.getTarget().isPrimaryKey()) { + return false; + } + } + return true; + } + protected void processRelationship(DbRelationship dbRelationship, ObjectId srcId, ObjectId targetId, boolean add) { for(DbJoin join : dbRelationship.getJoins()) { boolean srcPK = join.getSource().isPrimaryKey();