fix: resolve concurrency, data integrity, and correctness bugs in stock management#126
Conversation
…ck management 1. StockAdjustmentServiceImpl - Replace parallelStream with sequential forEach parallelStream on a non-thread-safe ArrayList caused lost updates and ArrayIndexOutOfBoundsException under concurrent load. JPA @Modifying queries called from parallel threads also bypass the @transactional boundary, making rollback unreliable and causing partial stock adjustments. 2. StockExitServiceImpl - Throw InventoryException on partial stock validation failure When getItemStockAndValidate filtered out items due to insufficient stock, all three exit flows (patient issue, self-consumption, store transfer) silently returned 0 with no indication of which items failed. Now throws InventoryException naming each failed item with its requested vs. available quantities. 3. ItemStockEntryRepo - Fix updateStock query to match on itemStockEntryID not vanSerialNo The WHERE clause used vanSerialNo (a mutable sync field) while the caller passed itemStockEntryID. In any record where the two diverge, stock was deducted from the wrong batch or not deducted at all. Fixed to use the stable primary key. 4. PatientReturnServiceImpl - Add @transactional and quantity guard to updateQuantityReturned Two separate DB updates (stock restore + exit quantity decrement) ran non-atomically with no upper-bound check. A crash after the first update permanently inflated stock. A caller could also return more than was dispensed. Now @transactional ensures both updates roll back together, and the guard rejects returnQuantity > issuedQuantity. 5. StockEntryServiceImpl - Replace deprecated Date mutation with java.time Date.setDate/setMonth are deprecated since Java 1.1 and do not handle month-boundary overflow (e.g. Jan 31 + 1 month wraps incorrectly) or DST transitions, producing a wrong expiry threshold that could serve expired stock or reject valid batches. Replaced with LocalDate.plusDays/plusMonths/plusWeeks via java.time.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|



Summary
StockAdjustmentServiceImpl— replacedparallelStream().forEach()with sequentialforEach()on sharedArrayListinstancesStockExitServiceImpl— replaced tautologyif (size == size)withif (size != size)throwingInventoryExceptionwith details of failed itemsItemStockEntryRepo.updateStock— changed WHERE clause fromvanSerialNoto the stable primary keyitemStockEntryID@Transactional(rollbackFor = Exception.class)toPatientReturnServiceImpl.updateQuantityReturnedfor atomicity, plus validation to reject invalid return quantitiesDate.setDate()/Date.setMonth()inStockEntryServiceImplwithLocalDateandZoneIdfor correct timezone-safe date arithmeticTest plan
updateStockcorrectly updates the right stock entry by primary key