Skip to content
Open

[FIX] #205

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ public class GroupBuyPost extends BaseTimeEntity {
private int currentQuantity; // ํ˜„์žฌ ์ธ์›

@Column(name = "rating_avg", nullable = true)
private double ratingAvg = 0.0; //๊ณต๊ตฌ ๊ธ€ ๋‹น ํ‰์ 
private Double ratingAvg = 0.0; //๊ณต๊ตฌ ๊ธ€ ๋‹น ํ‰์ 

@Column(name = "rating_sum", nullable = true)
private long ratingSum = 0L;
private Long ratingSum = 0L;

@Column(name = "rating_count", nullable = true)
private int ratingCount = 0;
private Integer ratingCount = 0;
Comment on lines 75 to +82
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue | ๐ŸŸ  Major

Nullable๋กœ ๋ฐ”๋€ rating ํ•„๋“œ๊ฐ€ null์ด๋ฉด addRating์—์„œ NPE ๊ฐ€๋Šฅ์„ฑ ์žˆ์Šต๋‹ˆ๋‹ค.

์ปฌ๋Ÿผ์ด nullable์ด๋ฉด ๊ธฐ์กด ๋ฐ์ดํ„ฐ๊ฐ€ null๋กœ ๋กœ๋“œ๋  ์ˆ˜ ์žˆ๊ณ , += ์—ฐ์‚ฐ์—์„œ ์˜คํ†  ์–ธ๋ฐ•์‹ฑ์œผ๋กœ NPE๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ addRating ์ง„์ž… ์‹œ null-safe ๋ณด์ •(๋˜๋Š” @PostLoad/@PrePersist, ๋ฐฑํ•„) ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ ์ œ์•ˆ ์ˆ˜์ •
 public void addRating(int score) {
   validateScore(score);

+  if (this.ratingSum == null) this.ratingSum = 0L;
+  if (this.ratingCount == null) this.ratingCount = 0;
+  if (this.ratingAvg == null) this.ratingAvg = 0.0;
+
   this.ratingSum += score;
   this.ratingCount += 1;

-  Double avg = (double) this.ratingSum / this.ratingCount;
+  double avg = (double) this.ratingSum / this.ratingCount;
   this.ratingAvg = Math.round(avg * 10) / 10.0;
 }

Also applies to: 210-218

๐Ÿค– Prompt for AI Agents
In `@src/main/java/org/sopt/poti/domain/groupbuy/entity/GroupBuyPost.java` around
lines 75 - 82, The rating fields ratingAvg, ratingSum, and ratingCount can be
null (DB nullable) which risks NPEs in addRating due to auto-unboxing; update
addRating to defensively handle nulls by treating null as 0 (e.g., coerce
ratingSum/ratingCount/ratingAvg to 0 before arithmetic) or add a
`@PostLoad/`@PrePersist initializer that backfills null fields to 0, and ensure
any setters also guard against null inputs; reference the fields ratingAvg,
ratingSum, ratingCount and the addRating method when applying the fix.


@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 30)
Expand Down Expand Up @@ -213,7 +213,7 @@ public void addRating(int score) {
this.ratingSum += score;
this.ratingCount += 1;

double avg = (double) this.ratingSum / this.ratingCount;
Double avg = (double) this.ratingSum / this.ratingCount;
this.ratingAvg = Math.round(avg * 10) / 10.0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public Long createReview(Long writerUserId, ReviewRequest request) {

// 2 ์ตœ์‹  ํŒŸ ์ƒํƒœ ์กฐํšŒ ๋ฐ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘
GroupBuyPost post = groupBuyService.getPostWithLock(postId);
int reviewCount = post.getRatingCount();
double postAvg = post.getRatingAvg();
Integer reviewCount = post.getRatingCount();
Double postAvg = post.getRatingAvg();
Comment on lines +44 to +45
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue | ๐ŸŸ  Major

postAvg/reviewCount null ๊ฐ€๋Šฅ์„ฑ ์ฒ˜๋ฆฌ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

GroupBuyPost์˜ rating ํ•„๋“œ๊ฐ€ nullable๋กœ ๋ฐ”๋€Œ์–ด null์ด ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•˜๋ฉด ๋‚ด๋ถ€ ์—ฐ์‚ฐ์—์„œ NPE/์˜ค๋™์ž‘ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. null-safe ๊ธฐ๋ณธ๊ฐ’ ๋ณด์ • ํ›„ ์ „๋‹ฌํ•˜๋Š” ํŽธ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ› ๏ธ ์ œ์•ˆ ์ˆ˜์ •
 GroupBuyPost post = groupBuyService.getPostWithLock(postId);
 Integer reviewCount = post.getRatingCount();
 Double postAvg = post.getRatingAvg();
+Integer safeReviewCount = (reviewCount != null) ? reviewCount : 0;
+Double safePostAvg = (postAvg != null) ? postAvg : 0.0;

 int postCount = groupBuyService.countPostsByLeader(sellerId);

 // 3 ํŒ๋งค์ž ํ‰์  ๋ฐ˜์˜
-userService.applyPostContribution(sellerId, postId, postAvg, reviewCount, postCount);
+userService.applyPostContribution(sellerId, postId, safePostAvg, safeReviewCount, postCount);

Also applies to: 50-50

๐Ÿค– Prompt for AI Agents
In
`@src/main/java/org/sopt/poti/domain/review/application/ReviewApplicationService.java`
around lines 44 - 45, The code in ReviewApplicationService reads Integer
reviewCount = post.getRatingCount() and Double postAvg = post.getRatingAvg() but
GroupBuyPost's rating fields can be null; update ReviewApplicationService to
null-safe defaults (e.g., reviewCount -> 0, postAvg -> 0.0) before any
arithmetic/logic, and use those non-null primitives or safe wrappers when
calling downstream methods; apply the same null-coalescing fix to the other
occurrence referenced (the second block around lines 50) so both
reviewCount/postAvg usages are protected.


int postCount = groupBuyService.countPostsByLeader(sellerId);

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/sopt/poti/domain/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ public class User extends BaseSoftDeleteEntity {
@Column(name = "rating_avg")
private Double ratingAvg;

@Column(name = "rating_sum", nullable = false)
private long ratingSum = 0L;
@Column(name = "rating_sum", nullable = true)
private Long ratingSum = 0L;

@Column(name = "rating_count", nullable = false)
private int ratingCount = 0;
@Column(name = "rating_count", nullable = true)
private Integer ratingCount = 0;
Comment on lines +59 to +63
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

โš ๏ธ Potential issue | ๐Ÿ”ด Critical

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

#!/bin/bash
# Find all usages of ratingSum and ratingCount in the codebase
rg -n --type java -C3 '(getRatingSum|getRatingCount|ratingSum|ratingCount)' --max-count=100

Repository: team-poti/POTI-SERVER

Length of output: 3802


๐Ÿ Script executed:

#!/bin/bash
# Check if Lombok is used and look for getter method patterns
rg -n --type java '@Getter|@Data|getRatingSum|getRatingCount' src/main/java/org/sopt/poti/domain/user/entity/User.java src/main/java/org/sopt/poti/domain/groupbuy/entity/GroupBuyPost.java -A2 -B2

echo "---"

# Search for all method calls and usages beyond the initial results
rg -n --type java 'getRatingSum|getRatingCount' --max-count=200

Repository: team-poti/POTI-SERVER

Length of output: 1083


๐Ÿ Script executed:

#!/bin/bash
# Check ReviewApplicationService context around the usage
cat -n src/main/java/org/sopt/poti/domain/review/application/ReviewApplicationService.java | sed -n '35,65p'

echo "---"

# Also check for any arithmetic operations or method calls on ratingCount/ratingSum
rg -n --type java '(ratingCount|ratingSum)\s*[+\-*/=<>]|ratingCount\s*\)|\+\s*(ratingCount|ratingSum)' -A2 -B2

Repository: team-poti/POTI-SERVER

Length of output: 3059


ratingSum/ratingCount nullable ์„ค์ • ์‹œ NPE ์œ„ํ—˜์„ฑ ํ™•์ธ ํ•„์š”

DB ์ปฌ๋Ÿผ์ด nullable = true๋กœ ์„ค์ •๋˜์–ด ์žˆ๋Š”๋ฐ, ์ฝ”๋“œ์—์„œ null ์ฒดํฌ ์—†์ด ์–ธ๋ฐ•์‹ฑ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ReviewApplicationService.java L44: Integer reviewCount = post.getRatingCount(); - null์ด ๋ฐ˜ํ™˜๋˜๋ฉด int ํ• ๋‹น ์‹œ NPE ๋ฐœ์ƒ
  • GroupBuyPost.java L213-217: this.ratingSum += score;, this.ratingCount += 1;, ๋‚˜๋ˆ—์…ˆ ์—ฐ์‚ฐ ๋“ฑ์—์„œ null ๊ฐ’ ์ฒ˜๋ฆฌ ์—†์Œ

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด๋‚˜ ๊ธฐ์กด ๋ฐ์ดํ„ฐ์— null์ด ์กด์žฌํ•œ๋‹ค๋ฉด ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ, ๋‹ค์Œ ์ค‘ ํ•˜๋‚˜๋ฅผ ํ™•์ธ/์ ์šฉํ•ด์ฃผ์„ธ์š”:

  • ๋ชจ๋“  ์‚ฌ์šฉ์ฒ˜์— null ์•ˆ์ „์„ฑ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
  • DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์œผ๋กœ ๊ธฐ์กด null ๊ฐ’์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ
  • nullable = false๋กœ ๋ณ€๊ฒฝ (๊ธฐ๋ณธ๊ฐ’ ์„ค์ •์ด ์ด๋ฏธ ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ)
๐Ÿค– Prompt for AI Agents
In `@src/main/java/org/sopt/poti/domain/user/entity/User.java` around lines 59 -
63, The User entity's ratingSum/ratingCount are declared nullable which risks
NPEs where callers (ReviewApplicationService: reviewCount =
post.getRatingCount(); and GroupBuyPost methods updating/reading ratings)
perform unboxing or arithmetic; fix by making the DB columns non-nullable and
preserving the zero defaults: set `@Column`(name = "rating_sum", nullable = false)
and `@Column`(name = "rating_count", nullable = false) on User.ratingSum and
User.ratingCount (keep the initializers 0L/0), and then audit
usagesโ€”specifically ReviewApplicationService where reviewCount is assigned and
GroupBuyPost methods that do this.ratingSum += score / this.ratingCount += 1 /
divisionsโ€”to rely on non-null values (no further null checks required after this
change) or, if you prefer code-side hardening instead, wrap reads with
Objects.requireNonNullElse(post.getRatingCount(), 0) and
Objects.requireNonNullElse(post.getRatingSum(), 0L) in ReviewApplicationService
and use the same null-safe reads inside GroupBuyPost before mutating or
dividing.


@Column(name = "rating_weighted_sum", nullable = false)
private double ratingWeightedSum = 0.0;
Expand Down