Skip to main content

Entity Relationship Overview

DriveX uses JPA (Java Persistence API) to manage four core entities and their relationships:

User Entity

The User entity represents customer accounts and administrative users.

Entity Definition

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    private String email;
    private String password_hash;
    
    @Column(name = "first_name")
    private String firstname;
    
    @Column(name = "last_name")
    private String lastname;
    
    private String phone_number;
    private String role;
    private Boolean is_active;
    private Timestamp created_at;
    private Timestamp updated_at;
    
    @Column(name = "profile_image")
    private String profileImage;
}

Fields Reference

id
Long
Primary key, auto-generated using IDENTITY strategy
username
String
Unique username for the user account
email
String
User’s email address, used as login identifier
password_hash
String
BCrypt hashed password (never store plaintext passwords)
firstname
String
User’s first name (maps to first_name column)
lastname
String
User’s last name (maps to last_name column)
phone_number
String
Contact phone number
role
String
User role (e.g., “USER”, “ADMIN”)
is_active
Boolean
Account activation status
profileImage
String
URL to user’s profile image (maps to profile_image column)

Vehicle Entity

The Vehicle entity represents cars and motorcycles available for rent.

Entity Definition

@Entity
@Table(name = "vehicles")
public class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false)
    private String reference;
    
    private String brand;
    private String model;
    private Integer hp;
    private Integer autonomy;
    
    @Column(name = "average_consumption")
    private Double averageconsumption;
    
    private String description;
    private BigDecimal price;
    private Integer year;
    
    @Column(name = "fuel_type")
    private String fuelType;
    
    private Long mileage;
    private String extras;
    
    @Column(name = "created_at")
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    private int doors;
    
    @Column(name = "vehicle_type")
    private String vehicleType;
    
    private String offers;
    
    @OneToMany(mappedBy = "vehicle", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonIgnoreProperties("vehicle")
    private List<VehicleImage> images = new ArrayList<>();
}

Fields Reference

id
Long
Primary key, auto-generated
reference
String
required
Unique reference code for the vehicle (non-nullable)
brand
String
Vehicle manufacturer (e.g., “FERRARI”, “TOYOTA”)
model
String
Vehicle model name
hp
Integer
Horsepower rating
autonomy
Integer
Range in kilometers (for electric vehicles)
averageconsumption
Double
Average fuel consumption (maps to average_consumption column)
description
String
Detailed vehicle description
price
BigDecimal
Daily rental price
year
Integer
Manufacturing year
fuelType
String
Fuel type (e.g., “GASOLINE”, “DIESEL”, “ELECTRIC”)
mileage
Long
Total kilometers driven
extras
String
Additional features and equipment
doors
int
Number of doors
vehicleType
String
Type of vehicle (e.g., “CAR”, “MOTORCYCLE”)
offers
String
Current promotional offers
images
List<VehicleImage>
One-to-many relationship with vehicle images. Cascades all operations and removes orphaned images.

Vehicle-Image Relationship

The Vehicle entity has a one-to-many relationship with VehicleImage:
@OneToMany(mappedBy = "vehicle", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnoreProperties("vehicle")
private List<VehicleImage> images = new ArrayList<>();
  • CascadeType.ALL: All JPA operations (persist, merge, remove) cascade to images
  • orphanRemoval = true: Automatically deletes images when removed from the list
  • @JsonIgnoreProperties(“vehicle”): Prevents circular reference in JSON serialization

Rental Entity

The Rental entity tracks vehicle reservations and bookings.

Entity Definition

@Entity
@Table(name = "rentals")
public class Rental {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "user_id", nullable = false)
    private Long userId;
    
    @Column(name = "vehicle_id", nullable = false)
    private Long vehicleId;
    
    @Column(name = "start_date", nullable = false)
    private LocalDate startDate;
    
    @Column(name = "end_date", nullable = false)
    private LocalDate endDate;
    
    @Column(name = "price", nullable = false, precision = 10, scale = 2)
    private BigDecimal price;
    
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private RentalStatus status = RentalStatus.RESERVED;
    
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    @PrePersist
    protected void onCreate() {
        this.createdAt = LocalDateTime.now();
        this.updatedAt = this.createdAt;
    }
    
    @PreUpdate
    protected void onUpdate() {
        this.updatedAt = LocalDateTime.now();
    }
}

Fields Reference

userId
Long
required
Foreign key reference to User entity
vehicleId
Long
required
Foreign key reference to Vehicle entity
startDate
LocalDate
required
Rental period start date
endDate
LocalDate
required
Rental period end date
price
BigDecimal
required
Total rental price (precision 10, scale 2 for currency)
status
RentalStatus
required
Current rental status, defaults to RESERVED

Rental Status Enum

The RentalStatus enum defines the rental lifecycle:
public enum RentalStatus {
    RESERVED,   // Initial booking state
    ACTIVE,     // Rental in progress
    COMPLETED,  // Rental finished
    CANCELLED   // Booking cancelled
}
Initial state when a user books a vehicle. Vehicle is held but rental hasn’t started.
Rental is currently in progress. User has picked up the vehicle.
Rental period has ended and vehicle has been returned.
Booking was cancelled before becoming active.

Automatic Timestamps

The Rental entity uses JPA lifecycle callbacks for automatic timestamp management:
@PrePersist
protected void onCreate() {
    this.createdAt = LocalDateTime.now();
    this.updatedAt = this.createdAt;
}

@PreUpdate
protected void onUpdate() {
    this.updatedAt = LocalDateTime.now();
}
The createdAt field uses updatable = false to prevent accidental modification after creation.

Favorite Entity

The Favorite entity implements a many-to-many relationship between Users and Vehicles for wishlists.

Entity Definition

@Entity
@Table(name = "favorites",
        uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "vehicle_id"}))
public class Favorite {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
    
    @ManyToOne
    @JoinColumn(name = "vehicle_id", nullable = false)
    private Vehicle vehicle;
}

Key Features

Unique Constraint

Prevents duplicate favorites with @UniqueConstraint on (user_id, vehicle_id)

Many-to-One Relationships

Both user and vehicle use @ManyToOne allowing multiple favorites per user and per vehicle

Usage Example

// Create a new favorite
Favorite favorite = new Favorite(user, vehicle);
favoriteRepository.save(favorite);
The unique constraint at the database level ensures a user cannot favorite the same vehicle multiple times.

Brand Enum

The Brand enum provides a comprehensive list of supported vehicle manufacturers:
public enum Brand {
    // Luxury and sports cars
    FERRARI, LAMBORGHINI, PORSCHE, MASERATI, BENTLEY, ROLLS_ROYCE,
    MCLAREN, PAGANI, KOENIGSEGG, LOTUS, ASTON_MARTIN, BUGATTI,
    
    // General brands
    AUDI, BMW, MERCEDES, VOLKSWAGEN, TOYOTA, HONDA, NISSAN, MAZDA,
    FORD, CHEVROLET, TESLA, ...
    
    // Motorcycles
    YAMAHA, KAWASAKI, DUCATI, HARLEY_DAVIDSON, TRIUMPH, ...
}
The Brand enum includes over 100 manufacturers across categories:
  • Luxury and sports cars (Ferrari, Lamborghini, Porsche, etc.)
  • General automotive brands (Toyota, Ford, Honda, etc.)
  • Motorcycle manufacturers (Yamaha, Ducati, Harley-Davidson, etc.)
  • Electric vehicle brands (Tesla, Lucid, Polestar, etc.)
  • Classic and historic brands (DeLorean, Packard, etc.)

Database Naming Conventions

DriveX uses a mixed naming strategy:
Java CodeDatabase Column
camelCasesnake_case
firstNamefirst_name
vehicleTypevehicle_type
createdAtcreated_at
Some fields like averageconsumption don’t follow this pattern consistently. Use @Column(name = "...") to explicitly map field names to column names.

Build docs developers (and LLMs) love