Skip to content

Flawed Unique ID Generation Causes Deterministic Constraint Violations #116

Description

@diksha78dev

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

  1. Start the application and authenticate as a Hospital user.
  2. Call the POST /api/orders endpoint multiple times to place equipment orders.
  3. Observe the returned orderCode (e.g., ORD-5432).
  4. 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.
  5. 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.

Metadata

Metadata

Assignees

Labels

ECSoC26-L3Hard (Advanced)ECSoc26Required for ECSOC SentinelenhancementNew feature or requestgood-backendExcellent backend implementationgood-issueGood issue

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions