🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG2026-02-18 16:05:12.000 ERROR 8842 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]] with root cause java.sql.SQLIntegrityConstraintViolationException: Column 'user_id' cannot be null

⚡ Quick Fix Works 80% of the time

Ensure you set the parent entity on the child entity before calling `save()`.

User user = new User("Deva"); Order order = new Order("Laptop"); order.setUser(user); // MUST SET PARENT user.getOrders().add(order); repo.save(user);

🧠 Why this Happens

Tap to expand the deep technical explanation

You attempted to INSERT a row into a child table (e.g., `orders`), but the foreign key column (`user_id`) was left null. The database schema defines this column as `NOT NULL`, so the database rejected the insert to prevent orphaned records.

The HITEC City Parking Spot Analogy:

It's like trying to mail a letter without writing the recipient's address. The post office (Database) refuses to accept it because the destination (Foreign Key) is mandatory.

🔁 How to Reproduce Confirm this is your error

Create `Order` entity with `@ManyToOne private User user;`. Create a new `Order`, do NOT set the user. Call `orderRepo.save(order)`. The DB will reject it.

🛠️ Solutions (5 Ways to Fix)

Solution 1✓ Most common cause

Set the parent on the child before saving

👉 Use this when manually managing relationships.

JPA requires you to set both sides of a bidirectional relationship before saving.

User user = new User("Deva"); Order order = new Order("Laptop"); // SET BOTH SIDES order.setUser(user); user.getOrders().add(order); repo.save(user); // CascadeType.ALL will save the order
Solution 2

Add helper methods to the Entity

👉 Use this to prevent forgetting to set both sides.

Encapsulate the logic to keep the relationship consistent inside the parent entity.

@Entity public class User { @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List<Order> orders = new ArrayList<>(); public void addOrder(Order order) { orders.add(order); order.setUser(this); // Automatically sets the foreign key } }
Solution 3

Verify JSON payload mapping

👉 Use this if the frontend is sending the ID, but it arrives as null.

If your DTO doesn't properly map the `userId` from the JSON, it will be null when you try to fetch and assign it.

public class OrderRequest { @NotNull private Long userId; // Ensure this is parsed from JSON private String item; }
Solution 4

Allow the foreign key to be nullable in DB

👉 Use this if the parent is genuinely optional.

Change the database schema to allow nulls. In JPA, use `@JoinColumn(nullable = true)`.

@Entity public class Order { @ManyToOne @JoinColumn(name = "user_id", nullable = true) // Allow null private User user; }
Solution 5

Fetch the parent before saving the child

👉 Use this if you only received the parent ID from the frontend.

Don't create a fake parent object. Fetch the actual managed entity from the DB and set it.

@Transactional public void createOrder(Long userId, OrderRequest req) { User user = userRepo.findById(userId).orElseThrow(); Order order = new Order(req.getItem()); order.setUser(user); // Set real, managed parent orderRepo.save(order); }

📋 Version Notes

Spring Boot 2.x

Throws SQLIntegrityConstraintViolationException.

Spring Boot 3.x

Identical behavior.

🛡️ How to Prevent This Next Time

Always use helper methods (e.g., `addOrder()`) in your entities to manage both sides of a relationship automatically.