everybody. 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):
// OrderRepository.java
package com.example.qpickshop.orders.repository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.repository.CrudRepository;
public interface OrderRepository extends CrudRepository<OrderEntity, Long> {
List<OrderEntity> findAllByUserId(long userId);
Optional<OrderEntity> findByUserIdAndId(long userId, long id);
}
// 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;
}
}
// OrderDto.java
package com.example.qpickshop.orders.api;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class OrderDto {
private Long id;
@NotNull
@Size(min = 1)
private List<OrderItemDto> orderItems;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<OrderItemDto> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItemDto> orderItems) {
this.orderItems = orderItems;
}
}
// OrderItemDto.java
package com.example.qpickshop.orders.api;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
public class OrderItemDto {
private Long id;
@NotNull
@Min(1)
private Long productId;
@NotNull
@Min(1)
private Integer quantity;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
}
// 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.