Skip to main content

Product Model

The ProductoPOJO represents a product entity in the e-commerce system. It encapsulates product information including identification, name, and price with built-in validation through value objects.

Model Structure

{
  "id": 67890,
  "nombre": "Laptop Dell XPS 15",
  "precio": {
    "value": 1299.99
  }
}

Fields

id
Long
required
Unique identifier for the product.
nombre
String
required
Product name or title.
precio
PrecioVO
required
Price value object with built-in validation to ensure price integrity.

Price Validation

The PrecioVO value object enforces price integrity through constructor validation. Any attempt to create an invalid price will throw an IllegalArgumentException.

Validation Rules

The price must satisfy ALL of the following conditions:
RuleRequirementException Message
Not NullPrice value cannot be null”El precio no puede ser nulo”
Non-NegativePrice must be >= 0”El precio no puede ser negativo”

Valid Price Examples

// Valid prices
{
  "precio": { "value": 0.0 }      // Free item
}
{
  "precio": { "value": 9.99 }     // Standard pricing
}
{
  "precio": { "value": 1299.99 }  // High-value item
}
{
  "precio": { "value": 0.01 }     // Minimum non-zero price
}
{
  "precio": { "value": 999999.99 } // Large price
}

Invalid Price Examples

// Null value
{
  "precio": { "value": null }
}  // IllegalArgumentException: "El precio no puede ser nulo"

// Negative price
{
  "precio": { "value": -10.50 }
}  // IllegalArgumentException: "El precio no puede ser negativo"

// Missing precio object
{
  "nombre": "Product Name"
}  // Validation error

Creating a Product

{
  "nombre": "Wireless Mouse",
  "precio": {
    "value": 29.99
  }
}

Updating a Price

The PrecioVO provides an actualizarPrecio() method that creates a new price value object:
PrecioVO currentPrice = producto.getPrecio();
PrecioVO newPrice = currentPrice.actualizarPrecio(24.99f);
producto.setPrecio(newPrice);
Price value objects are immutable. The actualizarPrecio() method returns a new PrecioVO instance rather than modifying the existing one. This ensures price history and audit trails remain consistent.

Complete Product Example

{
  "id": 12345,
  "nombre": "Samsung Galaxy S24 Ultra",
  "precio": {
    "value": 1199.99
  }
}

Price Display and Formatting

The PrecioVO class overrides toString() to return the string representation of the price value:
PrecioVO precio = new PrecioVO(99.99f);
System.out.println(precio.toString());  // Output: "99.99"
For currency formatting with symbols ($, €, etc.) and locale-specific formatting, implement formatting logic in your presentation layer or API response serializer.

Business Rules

Free Products

Products with a price of 0.0 are considered free:
{
  "id": 999,
  "nombre": "Free Sample Pack",
  "precio": { "value": 0.0 }
}

Price Updates

When updating product prices:
  • Always create a new PrecioVO instance
  • Log price changes for audit purposes
  • Consider implementing price history tracking
  • Validate business rules (e.g., maximum discount percentages)

Equality and Comparison

Two PrecioVO objects are equal if their values are equal:
PrecioVO precio1 = new PrecioVO(99.99f);
PrecioVO precio2 = new PrecioVO(99.99f);
PrecioVO precio3 = new PrecioVO(89.99f);

precio1.equals(precio2);  // true
precio1.equals(precio3);  // false

API Integration Examples

GET /productos/

Response
{
  "id": 42,
  "nombre": "Mechanical Keyboard RGB",
  "precio": {
    "value": 149.99
  }
}

POST /productos

Request
{
  "nombre": "USB-C Hub 7-in-1",
  "precio": {
    "value": 49.99
  }
}
Response (201 Created)
{
  "id": 543,
  "nombre": "USB-C Hub 7-in-1",
  "precio": {
    "value": 49.99
  }
}

PUT /productos/

Request
{
  "nombre": "USB-C Hub 7-in-1 (Updated)",
  "precio": {
    "value": 39.99
  }
}

Error Handling

Invalid Price Errors

400 Bad Request - Null Price
{
  "error": "IllegalArgumentException",
  "message": "El precio no puede ser nulo",
  "field": "precio.value"
}
400 Bad Request - Negative Price
{
  "error": "IllegalArgumentException",
  "message": "El precio no puede ser negativo",
  "field": "precio.value",
  "provided": -25.00
}
  • User Model - User entity with password validation

Source Code Reference

  • ProductoPOJO: src/main/java/com/example/demo/producto/domain/models/ProductoPOJO.java:11
  • PrecioVO: src/main/java/com/example/demo/producto/domain/vo/PrecioVO.java:6

Build docs developers (and LLMs) love