I’m doing work at uni, I need to write Backend in Java Spring Boot for online store. There was a difficulty with the realization of the functionality of order creation.
My code (let’s omit controllers):
// OrderService.java
package com.example.qpickshop.orders.service;
import java.util.List;
import java.util.stream.StreamSupport;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderService {
private final UserService userService;
private final OrderRepository repository;
private final OrderItemService orderItemService;
private final CartItemService cartItemService;
public OrderService(CartItemService cartItemService, OrderRepository repository, OrderItemService orderItemService,
UserService userService) {
this.repository = repository;
this.orderItemService = orderItemService;
this.userService = userService;
this.cartItemService = cartItemService;
}
@Transactional
public OrderEntity create(OrderEntity entity, Long userId) {
if (entity == null) {
throw new IllegalArgumentException("Entity is null");
}
entity.setUser(userService.get(userId));
OrderEntity order = repository.save(entity);
orderItemService.createMany(order.getItems(), order);
return order;
}
}
// OrderItemService.java
package com.example.qpickshop.orders.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OrderItemService {
private final OrderItemRepository repository;
public OrderItemService(OrderItemRepository repository) {
this.repository = repository;
}
@Transactional
public List<OrderItemEntity> createMany(List<OrderItemEntity> orderItems, OrderEntity order) {
if (order == null) {
throw new IllegalArgumentException("Order is null");
}
for (int i = 0; i < orderItems.size(); i++) {
orderItems.get(i).setOrder(order);
}
repository.saveAll(orderItems);
return orderItems;
}
}
// OrderEntity.java
package com.example.qpickshop.orders.model;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
@Entity
@Table(name = "orders")
public class OrderEntity extends BaseEntity {
@ManyToOne
@JoinColumn(name = "userId", nullable = false)
private UserEntity user;
@Column(nullable = false)
private Date date = new Date();
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private List<OrderItemEntity> items = new ArrayList<>();
public OrderEntity() {
}
public OrderEntity(UserEntity user) {
this.user = user;
this.date = new Date();
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
if (!user.getOrders().contains(this)) {
user.getOrders().add(this);
}
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public List<OrderItemEntity> getItems() {
return items;
}
public void setItems(List<OrderItemEntity> items) {
this.items = items;
}
public void addItem(OrderItemEntity orderItem) {
if (orderItem.getOrder() != this) {
orderItem.setOrder(this);
}
items.add(orderItem);
}
}
// OrderItemEntity.java
package com.example.qpickshop.orders.model;
import java.util.Objects;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "orderItems")
public class OrderItemEntity extends BaseEntity {
@ManyToOne
@JoinColumn(name = "productId", nullable = false)
private ProductEntity product;
@ManyToOne
@JoinColumn(name = "orderId", nullable = false)
private OrderEntity order;
@Column(nullable = false)
private Integer quantity;
public OrderItemEntity() {
}
public OrderItemEntity(ProductEntity product, Integer quantity) {
this.product = product;
this.quantity = quantity;
}
public OrderEntity getOrder() {
return order;
}
public void setOrder(OrderEntity order) {
this.order = order;
if (!order.getItems().contains(this)) {
order.getItems().add(this);
}
}
public ProductEntity getProduct() {
return product;
}
public void setProduct(ProductEntity product) {
this.product = product;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
}
// UserEntity.java
package com.example.qpickshop.users.model;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
@Entity
@Table(name = "users")
public class UserEntity extends BaseEntity {
@Column(nullable = false, unique = true, length = 50)
private String email;
@Column(nullable = false)
private String password;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<OrderEntity> orders = new HashSet<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<CartItemEntity> cartItems = new HashSet<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@OrderBy("id ASC")
private Set<FavouriteProductEntity> favouriteProducts = new HashSet<>();
public UserEntity() {
}
public UserEntity(String email, String password) {
this.email = email;
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<OrderEntity> getOrders() {
return orders;
}
public void addOrder(OrderEntity order) {
if (order.getUser() != this) {
order.setUser(this);
}
orders.add(order);
}
}
The actual problem: when I execute OrderService.create, I get an error:
NULL not allowed for column "ORDER_ID"; SQL statement:
insert into order_items (order_id,product_id,quantity,id) values (?,?,?,?) [23502-224]] [insert into order_items (order_id,product_id,quantity,id) values (?,?,?,?)]; SQL [insert into order_items (order_id,product_id,quantity,id) values (?,?,?,?)]; constraint [null]] with root cause
Please advise me how I can fix this error. Perhaps I should redesign my models – I am ready for it, the main thing is to preserve the functionality of the application.
My suspicions are that entity.setUser… is to blame, because everything works without it (well, if you ignore the error USER_ID cannot be NULL).