Problem Description
The application generates unique business codes for both Equipment and EquipmentOrder using System.currentTimeMillis() % 10000. This evaluates to a number between 0 and 9999. Because it is a modulo of 10,000 milliseconds, the possible generated values cycle and repeat completely every 10 seconds. Since these fields are constrained by @Column(unique = true) in the database, this logic guarantees frequent and deterministic DataIntegrityViolationException (duplicate keys) during normal operation.
Steps to Reproduce
- Start the application and authenticate as a Hospital user.
- Call the
POST /api/orders endpoint multiple times to place equipment orders.
- Observe the returned
orderCode (e.g., ORD-5432).
- Because the range of generated IDs is restricted to 0-9999 and resets every 10 seconds, creating a few dozen orders over a short period (or creating an order at the exact same millisecond offset as a previous one) will inevitably trigger a collision.
- The application will crash with a 500 Internal Server Error (specifically a database constraint violation on
uk_order_code).
Expected Behavior
The application should use a sufficiently random or sequential ID generation strategy (like UUIDs or a database sequence) that guarantees uniqueness for constraints and prevents database collisions.
Actual Behavior
The custom generation logic restricts the possible unique pool to just 10,000 combinations that repeat every 10 seconds. This causes the database to reject new orders and equipment creations once a collision inevitably occurs.
Evidence from Code
In OrderService.java:
public EquipmentOrder placeOrder(EquipmentOrder order) {
if (order.getOrderCode() == null) {
// Evaluates to ORD-0 through ORD-9999 and repeats every 10 seconds
order.setOrderCode("ORD-" + System.currentTimeMillis() % 10000);
}
return orderRepository.save(order);
}
In EquipmentOrder.java:
@Column(nullable = false, unique = true, length = 50)
private String orderCode;
(The exact same flaw exists in EquipmentService.java for generating equipmentCode)
Environment
- Backend: Spring Boot 3.x
- Spring Data JPA
Impact
Critical. It guarantees a catastrophic failure of core CRUD operations (adding equipment and placing orders) in production. Users will be randomly and permanently blocked from creating new records due to 500 Server Errors caused by database constraints.
Additional Notes
Replacing the ID generation logic with UUID.randomUUID().toString() or a custom Hibernate sequence generator (e.g., @GenericGenerator) will immediately resolve this issue.
Problem Description
The application generates unique business codes for both
EquipmentandEquipmentOrderusingSystem.currentTimeMillis() % 10000. This evaluates to a number between 0 and 9999. Because it is a modulo of 10,000 milliseconds, the possible generated values cycle and repeat completely every 10 seconds. Since these fields are constrained by@Column(unique = true)in the database, this logic guarantees frequent and deterministicDataIntegrityViolationException(duplicate keys) during normal operation.Steps to Reproduce
POST /api/ordersendpoint multiple times to place equipment orders.orderCode(e.g.,ORD-5432).uk_order_code).Expected Behavior
The application should use a sufficiently random or sequential ID generation strategy (like UUIDs or a database sequence) that guarantees uniqueness for constraints and prevents database collisions.
Actual Behavior
The custom generation logic restricts the possible unique pool to just 10,000 combinations that repeat every 10 seconds. This causes the database to reject new orders and equipment creations once a collision inevitably occurs.
Evidence from Code
In
OrderService.java:In
EquipmentOrder.java:(The exact same flaw exists in
EquipmentService.javafor generatingequipmentCode)Environment
Impact
Critical. It guarantees a catastrophic failure of core CRUD operations (adding equipment and placing orders) in production. Users will be randomly and permanently blocked from creating new records due to 500 Server Errors caused by database constraints.
Additional Notes
Replacing the ID generation logic with
UUID.randomUUID().toString()or a custom Hibernate sequence generator (e.g.,@GenericGenerator) will immediately resolve this issue.