Skip to content

fix:resourceUpload#320

Open
msslulu wants to merge 4 commits into
opentiny:developfrom
msslulu:fix/resourceUpload
Open

fix:resourceUpload#320
msslulu wants to merge 4 commits into
opentiny:developfrom
msslulu:fix/resourceUpload

Conversation

@msslulu

@msslulu msslulu commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

重复上传图片返回已存在的图片url

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
    • Improved upload handling for already-uploaded content: when a matching content hash is detected, uploads are no longer blocked by an error and the existing resource is reused instead.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 521a2673-1b39-4d35-a472-db19868523f7

📥 Commits

Reviewing files that changed from the base of the PR and between a28aab5 and b9504cd.

📒 Files selected for processing (1)
  • base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java
👮 Files not reviewed due to content moderation or server errors (1)
  • base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the main change by pointing to resourceUpload, though it is terse and not very descriptive.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java (2)

178-210: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add/confirm test coverage for repeated-hash uploads.

No test changes are included in this PR context. Since the fix's whole purpose is "allow repeated uploads by hash," a regression test asserting two uploads with the same hash both succeed (and previously would have failed with CM003) would lock in this behavior.

Want me to draft a unit test for resourceUpload covering this case?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`
around lines 178 - 210, Add or update a regression test for
ResourceServiceImpl.resourceUpload that verifies two uploads with the same hash
both succeed and no CM003 is thrown; the test should exercise the
repeated-upload path in resourceUpload and assert the second call is accepted
rather than rejected by the hash check. Use the resourceUpload method and the
baseMapper.createResource/queryResourceById flow to locate the behavior under
test, and cover the case where the same hash is uploaded twice.

190-202: 🧹 Nitpick | 🔵 Trivial

Unbounded storage growth from duplicate uploads.

Without a dedup check, each repeat upload of the same image persists another full resourceData/thumbnailData base64 blob row. This is the intended tradeoff per the PR, but worth flagging for operational awareness (storage/cost growth, no cleanup path for orphaned duplicates).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`
around lines 190 - 202, The ResourceServiceImpl upload flow currently always
persists a new resourceData and thumbnailData blob for repeat image uploads,
causing unbounded duplicate storage growth. In the code around the
resourceUrl/thumbnailUrl setup in ResourceServiceImpl, add a deduplication check
before saving or reusing the existing record so repeated uploads of the same
content do not create another full base64 row. Use the existing
resource/resourceData handling and the thumbnail generation path to locate the
save logic, and make sure duplicate detection is applied before calling
createThumbnail or persisting the new data.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`:
- Around line 178-210: Add or update a regression test for
ResourceServiceImpl.resourceUpload that verifies two uploads with the same hash
both succeed and no CM003 is thrown; the test should exercise the
repeated-upload path in resourceUpload and assert the second call is accepted
rather than rejected by the hash check. Use the resourceUpload method and the
baseMapper.createResource/queryResourceById flow to locate the behavior under
test, and cover the case where the same hash is uploaded twice.
- Around line 190-202: The ResourceServiceImpl upload flow currently always
persists a new resourceData and thumbnailData blob for repeat image uploads,
causing unbounded duplicate storage growth. In the code around the
resourceUrl/thumbnailUrl setup in ResourceServiceImpl, add a deduplication check
before saving or reusing the existing record so repeated uploads of the same
content do not create another full base64 row. Use the existing
resource/resourceData handling and the thumbnail generation path to locate the
save logic, and make sure duplicate detection is applied before calling
createThumbnail or persisting the new data.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 84636700-93bb-43ba-b24b-3292a5b54e03

📥 Commits

Reviewing files that changed from the base of the PR and between 0898769 and 9efbcce.

📒 Files selected for processing (1)
  • base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java (1)

203-216: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

TOCTOU on hash dedupe can still create duplicate resources. selectOne followed by createResource is still a check-then-act race, and t_resource has no unique constraint on hash (only category,name,tenant_id), so concurrent uploads of the same file can insert duplicate rows. Add a unique constraint on hash (or the tenant-scoped equivalent) and handle duplicate-key conflicts in the insert path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`
around lines 203 - 216, The hash-based deduplication in ResourceServiceImpl’s
create/read flow is still vulnerable to concurrent inserts because it checks
with selectOne before calling createResource. Add a database-level unique
constraint on hash (or the correct tenant-scoped hash key) and update the create
path to catch and translate duplicate-key failures around
baseMapper.createResource so concurrent uploads return the existing resource
instead of creating duplicates.
🧹 Nitpick comments (1)
base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java (1)

198-209: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Move duplicate-hash check before thumbnail generation.

The hash lookup (Lines 203-209) runs after Line 201 already generates the thumbnail via ImageThumbnailGenerator.createThumbnail(...). Since this PR's goal is to let repeated uploads of the same image short-circuit to the existing resource, that expensive image processing work is wasted on every duplicate re-upload — the exact case this change is meant to optimize.

♻️ Proposed reorder
-        if (!StringUtils.isEmpty(resourceData)) {
-            resource.setResourceUrl(resourceUrl);
-            resource.setThumbnailUrl(thumbnailUrl);
-            resource.setThumbnailData(ImageThumbnailGenerator.createThumbnail(resource.getResourceData(), 200, 200));
-        }
         QueryWrapper<Resource> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("hash", resource.getHash());
         // 接入租户系统需添加租户id查询
         Resource resourceResult = this.baseMapper.selectOne(queryWrapper);
         if (resourceResult != null) {
             return resourceResult;
         }
+        if (!StringUtils.isEmpty(resourceData)) {
+            resource.setResourceUrl(resourceUrl);
+            resource.setThumbnailUrl(thumbnailUrl);
+            resource.setThumbnailData(ImageThumbnailGenerator.createThumbnail(resource.getResourceData(), 200, 200));
+        }
         int createResult = this.baseMapper.createResource(resource);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`
around lines 198 - 209, The duplicate-hash lookup in ResourceServiceImpl should
run before any thumbnail generation so repeated uploads can short-circuit early.
Move the QueryWrapper/selectOne hash check ahead of the
ImageThumbnailGenerator.createThumbnail call in the resource handling flow, and
only set resourceUrl/thumbnailUrl/thumbnailData after confirming no existing
Resource is returned. Use the ResourceServiceImpl resource processing block and
the createThumbnail/hash lookup logic to locate the reorder point.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`:
- Around line 203-216: The hash-based deduplication in ResourceServiceImpl’s
create/read flow is still vulnerable to concurrent inserts because it checks
with selectOne before calling createResource. Add a database-level unique
constraint on hash (or the correct tenant-scoped hash key) and update the create
path to catch and translate duplicate-key failures around
baseMapper.createResource so concurrent uploads return the existing resource
instead of creating duplicates.

---

Nitpick comments:
In
`@base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java`:
- Around line 198-209: The duplicate-hash lookup in ResourceServiceImpl should
run before any thumbnail generation so repeated uploads can short-circuit early.
Move the QueryWrapper/selectOne hash check ahead of the
ImageThumbnailGenerator.createThumbnail call in the resource handling flow, and
only set resourceUrl/thumbnailUrl/thumbnailData after confirming no existing
Resource is returned. Use the ResourceServiceImpl resource processing block and
the createThumbnail/hash lookup logic to locate the reorder point.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3ab8dfe3-4fd0-4778-94f5-bdc5352a6f1b

📥 Commits

Reviewing files that changed from the base of the PR and between 9efbcce and d46f8f4.

📒 Files selected for processing (1)
  • base/src/main/java/com/tinyengine/it/service/material/impl/ResourceServiceImpl.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants