[英]Why unidirectional @OneToMany update is not working
我對 JPA 和 ORM 概念完全陌生,所以我希望有人能清楚地解釋我的代碼可能存在什么問題。
@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;
}
最初,客戶實體是通過用戶界面創建並成功持久化的。 后來,客戶有訂單,我用 CustomerOrder 更新客戶如下:
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);
}
}
EntityManage 合並后,我得到以下異常。 我的印象是我不需要自己顯式地保留 LineItem 和 CustomerOrder 實體。 我認為 JPA 將保留 object 圖中的所有實體。 為什么我會收到此異常? (我正在使用帶有 EclipseLink JPA 的 GlassFish 5.1 服務器)
提前致謝。
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.
順便說一句,目前,所有映射關系都是單向的,因為我沒有看到任何使用雙向映射的理由。 但是,通過使這些映射雙向進行,我會得到什么嗎?
您的 OneToMany 映射缺少連接規范或 mappedBy 值
我注意到了。 首先你應該向數據庫提交新訂單。然后你應該將它與用戶鏈接。我不確定這是否解決了你的問題,但這是一個問題。你能檢查一下嗎?
在我看來,如果您將客戶信息保存在您的 Order 實體中,它可能會解決這個問題。
@ManyToOne ()
private Customer customer;
在您的客戶實體中,您應該將mappedBy=customer作為訂單字段。
之后,您可以為特定訂單給客戶,而不是為客戶下訂單。 在我看來,它將實現更好的關系映射;
order.setCustomer(customer);
我希望我理解正確,這將解決您的問題。 當您為訂單提供客戶詳細信息時,您不需要為同一客戶提供訂單列表詳細信息。 只有其中一個就足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.