[英]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.