I am completely new to JPA and ORM concept, so I am hoping someone can lucidly explain what might be the problem with my code.
@Entity
@Table(name = "PERSISTENCE_customer")
public class Customer implements Serializable {
private static final long serialVersionUID = 1005220876458L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
@OneToMany (cascade = CascadeType.ALL, orphanRemoval = true)
private List<CustomerOrder> orders;
}
@Entity
@Table(name = "PERSISTENCE_ORDER")
public class CustomerOrder implements Serializable{
private static final long serialVersionUID = 199102142021L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
String status;
@NotNull
@OneToMany (cascade = CascadeType.ALL, orphanRemoval = true)
private List<LineItem> lineItems = new ArrayList();
@NotNull
private String orderNumber;
................
................
}
@Entity
@Table(name = "PERSISTENCE_LINEITEM")
public class LineItem implements Serializable {
private static final long serialVersionUID = 1991217202100959L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
private Integer quantity;
@NotNull
private Part part;
}
Initially, the Customer entity is created through the user interface and persisted successfully. Later, the customer has an order and I update the Customer with CustomerOrder as follow:
private void UpdateCustomer(Customer customer) {
FacesContext fc = FacesContext.getCurrentInstance();
List<ShoppingCartItem> shoppingCart = getShoppingCart();
CustomerOrder order = new CustomerOrder();
List<CustomerOrder> orders = customer.getOrders();
order.setLastUpdated(new Date());
order.setOrderNumber(getInvoiceNumber());
List<LineItem> lineItems = shoppingCart
.stream()
.map(e -> (new LineItem(e.getPart(), e.getQuantity())))
.collect(Collectors.toList());
order.setLineItems(lineItems);
order.setStatus("Pending Shipment");
order.setTotal(getTotal());
orders.add(order);
customer.setOrders(orders);
try {
updateOrders(customer, orders);
fc.addMessage(null,
new FacesMessage("Customer order added successfuly"));
} catch (ListServiceException e) {
FacesMessage errMsg = new FacesMessage(FacesMessage.SEVERITY_FATAL,
"Error while adding customer order: ", e.getMessage());
fc.addMessage(null, errMsg);
}
}
private void updateOrders(Customer cust, List<CustomerOrder> orders) throws ListServiceException {
try { //em is the EntityManager injected as the field member
if (em != null) {
if (em.isOpen()) {
Customer c = getCustomer(cust.getId());
c.setOrders(orders);
em.merge(c);
} else {
logger.severe("Entity manager is closed");
}
else {
logger.severe("Entity manager is NULL");
}
} catch (Exception e) {
throw ThrowListServiceException.wrapException(e);
}
}
Once the EntityManage merges I get the following exception. I was under the impression that I don't need to explicitly persist the LineItem and CustomerOrder entities myself. I thought that the JPA will persist all the entities in the object graph. Why am I getting this exception? (I am using GlassFish 5.1 server with EclipseLink JPA)
Thanks in advance.
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: Column 'ORDERS_ID' cannot accept a NULL value.
Error Code: 30000
Call: INSERT INTO PERSISTENCE_CUSTOMER_PERSISTENCE_ORDER (orders_ID, Customer_ID) VALUES (?, ?)
bind => [2 parameters bound]
Query: DataModifyQuery(name="orders" sql="INSERT INTO PERSISTENCE_USER_PERSISTENCE_ORDER (orders_ID, User_ID) VALUES (?, ?)")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:905)
...............................
.................................
Caused by: java.sql.SQLIntegrityConstraintViolationException: Column 'ORDERS_ID' cannot accept a NULL value.
By the way, at moment, all the mapping relationships are unidirectional because I didn't see any reasons to use bidirectional mapping. However, would I gain anything by making these mappings bidirectionals?
Your OneToMany mapping is missing join specification or mappedBy value
I noticed that. Firstly You should commit new order to database.Then you should link it with user.I'm not sure if this solves your problem but this is a problem.Can you check it?
In my opinion, if you keep customer information in your Order entity, it may solve this problem.
@ManyToOne ()
private Customer customer;
And in your Customer entity you should put mappedBy=customer for orders field.
After that, instead of giving orders for customer, you can give customer for a specific order. In my opinion it will achieve a better relationship mapping;
order.setCustomer(customer);
I hope i understood it right and this will solve your problem. When you give customer detail for order, you dont need to give orderlist detail for the same customer. Only one of them should be enough.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.