Aias00 opened a new issue, #7772: URL: https://github.com/apache/shenyu/issues/7772
### Current behavior `TagServiceImpl.update()` creates a partial TagDO from the DTO without `ext`. It then calls `updateSubTags()`, which replaces the edited node in its working map with another partial object lacking the persisted extension state. Descendants are rebuilt from this incomplete parent. On a parent move, the edited node's final selective update changes `parent_tag_id` but leaves its old `ext` in the database because the new object's ext is null. Descendants meanwhile get a truncated extension chain that contains the edited node but omits its old/new ancestors. ### Locations / actual entry - [TagServiceImpl.java:95–100,172–240](https://github.com/apache/shenyu/blob/66d7d954ca37d651a5ad916f988a8081157a7ab4/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/TagServiceImpl.java#L95) - [TagDO.buildTagDO():158–176](https://github.com/apache/shenyu/blob/66d7d954ca37d651a5ad916f988a8081157a7ab4/shenyu-admin/src/main/java/org/apache/shenyu/admin/model/entity/TagDO.java#L158) does not populate ext. - [tag-sqlmap.xml:151–174](https://github.com/apache/shenyu/blob/66d7d954ca37d651a5ad916f988a8081157a7ab4/shenyu-admin/src/main/resources/mappers/tag-sqlmap.xml#L151) selectively retains an old ext when the update supplies null. - `PUT /tag/id/{id}` calls `tagService.update(tagDTO)`. ### Reproduction / validation A Java probe compiled the current service and TagDO, created root tags A/B, C under A, and D under C through the actual service create methods. It then moved C under B using actual `update()`. Mapper I/O was replaced by an in-memory store with copy-on-read and the same selective-update semantics as the XML. The service's extension construction and recursion ran unchanged: ```text BEFORE C.ext=[A] D.ext=[C, A] AFTER C.parent=B C.ext=[A] D.ext=[C] ``` Expected: C's extension ancestry refers to B, and D's ancestry is C → B. The before state is the passing create control. An independent reviewer confirmed the partial-parent replacement and selective persistence behavior. No deployed database or frontend was used. ### Impact / scope Successful edits can leave `parentTagId` and the API's serialized extension ancestry inconsistent, and remove ancestor metadata from descendants. Even a rename of a non-root node can rebuild descendants from a parent object missing its previous ext. This report does not claim a specific Swagger pull failure or data loss beyond the observed extension state. ### Suggested fix Merge the update with the persisted edited node, rebuild its own extension from the effective new parent when needed, and use that complete node as the recursion parent. Persist parent/descendant extension state consistently within the existing transaction while preserving unrelated extension fields. ### Related existing work #6552 fixed missing transaction rollback around recursive updates. This mismatch occurs when every write succeeds, so adding a transaction does not fix it. #6520 concerns creating a tag whose parent does not exist. Current-tag ancestry reconstruction is a separate deterministic correctness defect. ### Reviewed revision Apache ShenYu 2.7.2-SNAPSHOT, `master@66d7d954ca37d651a5ad916f988a8081157a7ab4`. P2 / Medium; high confidence. Unit-test and CI issue categories excluded. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
