Skip to content
Merged
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 @@ -3,7 +3,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.*;

@RestController
@RequestMapping("/api/data-models")
Expand All @@ -12,15 +12,22 @@ public class DataModelCartController {
@Autowired
private DataModelRepository dataModelRepository;

/**
* [임시] 사용자별 장바구니 목록을 저장할 Map
* - key: 사용자 ID (문자열)
* - value: 해당 사용자가 장바구니에 담은 DataModel 리스트
*/
private Map<String, List<DataModel>> userCartMap = new HashMap<>();
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Review concurrency implications of shared map usage.
Because userCartMap is a simple HashMap that is being modified, consider using a concurrent data structure or synchronizing access if multiple threads can call these endpoints simultaneously (which is common in a Spring Boot application).

For instance, switching to a thread-safe structure like ConcurrentHashMap could prevent race conditions.

-private Map<String, List<DataModel>> userCartMap = new HashMap<>();
+private Map<String, List<DataModel>> userCartMap = new ConcurrentHashMap<>();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private Map<String, List<DataModel>> userCartMap = new HashMap<>();
private Map<String, List<DataModel>> userCartMap = new ConcurrentHashMap<>();


//모델 생성,삭제,추가,수정
@GetMapping
public List<DataModel> getAll() {
return dataModelRepository.findAll();
}

@GetMapping("/{id}")
public DataModel getById(@PathVariable String id) {
return dataModelRepository.findById(id)
.orElse(null);
return dataModelRepository.findById(id).orElse(null);
}

@PostMapping
Expand All @@ -38,4 +45,28 @@ public DataModel update(@PathVariable String id, @RequestBody DataModel model) {
public void delete(@PathVariable String id) {
dataModelRepository.deleteById(id);
}

//장바구니 기능
@PostMapping("/cart/{userId}/{modelId}")
public List<DataModel> addToCart(@PathVariable String userId,
@PathVariable String modelId) {
DataModel selectedModel = dataModelRepository.findById(modelId).orElse(null);
if (selectedModel == null) {
return Collections.emptyList();
}

List<DataModel> cartList = userCartMap.getOrDefault(userId, new ArrayList<>());

cartList.add(selectedModel);

userCartMap.put(userId, cartList);

return cartList;
}

//장바구니 목록 조회
@GetMapping("/cart/{userId}")
public List<DataModel> getCart(@PathVariable String userId) {
return userCartMap.getOrDefault(userId, Collections.emptyList());
}
Comment on lines +67 to +71
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Thread-safety concerns in cart operations confirmed

The verification reveals that userCartMap is implemented using a standard HashMap without any thread-safety mechanisms:

private Map<String, List<DataModel>> userCartMap = new HashMap<>();

This implementation is not thread-safe and could lead to data races when:

  • Multiple threads access getOrDefault and put operations concurrently
  • The underlying ArrayList is modified during cart updates

Recommendations:

  • Replace HashMap with ConcurrentHashMap
  • Consider using Collections.synchronizedList() for the cart list
  • Alternatively, implement method-level synchronization using the synchronized keyword
🔗 Analysis chain

Verify cart retrieval in concurrent scenarios.
Using the getCart method in parallel with addToCart on the same user ID might lead to unexpected results if underlying modifications are not thread-safe. Consider a concurrency strategy or a lightweight read-write lock.

Below is a shell script you could use to check for concurrency references in your codebase for better insights:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching for concurrency-related annotations or logic in the project.
rg -A 5 "synchronized|volatile|ConcurrentHashMap|Lock|ReadWriteLock|@Async|@Scheduled"

Length of output: 88


Script:

#!/bin/bash
# Let's check the implementation of userCartMap to understand its thread-safety
ast-grep --pattern 'userCartMap'

# Also check for any Map initialization or declaration
rg -l "Map[<].*[>].*=.*new"

Length of output: 840

}
Loading