I have a parent entity named Order
@Entity
public class Order {
@OrderBy("orderLine ASC")
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "orderid")
protected Set<OrderDetail> details = null;
// ... other fields ... //
public Set<OrderDetail> getDetails() { return details; }
public void setDetails(Set<OrderDetail> details) { this.details = details; }
// ... getters/setters for other fields ... //
}
And I have a child entity named OrderDetail
@Entity
public class OrderDetail {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id = null;
@Column(name = "orderId")
protected Long orderId = null;
// ... other fields ... //
public Long getOrderId() { return orderId; }
public void setOrderId(Long orderId) { this.orderId = orderId; }
// ... getters/setters for other fields ... //
}
For a particular Order, I have 2 existing detail records. I bring it up on my screen and add a detail record. I then send the Order object to the controller where it is handled by
@Override
public Order saveOrUpdate(OrderOld order, String userName, Long companyId) {
// set passed in values
order.setUsername(userName);
order.setCompanyId(companyId);
// update billing consumer
order.getBillingConsumer().setCompanyId(companyId);
order.getBillingConsumer().setUsername(userName);
order.setBillingConsumer(consumerDao.saveOrUpdate(order.getBillingConsumer()));
// update shippingConsumer
order.getShippingConsumer().setCompanyId(companyId);
order.getShippingConsumer().setUsername(userName);
order.setShippingConsumer(consumerDao.saveOrUpdate(order.getShippingConsumer()));
// update details or insert new details
for (OrderDetail detail : order.getDetails()) {
detail.setCompanyId(companyId);
detail.setUsername(userName);
detail.setOrderId(order.getId());
orderDetailDao.saveOrUpdate(detail);
}
// remove any details that the user removed.
if (order.getId() != null) {
List<OrderDetail> detailsToRemove = new ArrayList<>();
Order oldOrder = orderDao.get(order.getId(), companyId); // LINE 172
for (OrderDetail oldDetail : oldOrder.getDetails()) {
boolean found = false;
for (OrderDetail newDetail : order.getDetails()) {
if (Objects.equals(oldDetail.getId(), newDetail.getId())) {
found = true;
break;
}
}
if (!found) {
detailsToRemove.add(oldDetail);
}
}
for (OrderDetail detailToRemove : detailsToRemove) {
orderDetailDao.remove(detailToRemove);
}
}
// save the order
OrderOld savedOrder = orderDao.saveOrUpdate(order); // LINE 190
// return orderDao.saveOrUpdate(order);
return orderDao.get(savedOrder.getId(), companyId);
}
In my logs, I can see that two of the details are updated, and one is inserted. This is as it should be. Then I see the select Order from LINE 172, and that is fine. Then I see the update to Order on LINE 190. Then unexplicably it does this...
2022-06-10T09:15:43,190 DEBUG [http-nio-8080-exec-82] o.h.e.j.s.SqlStatementLogger: update dbo.tblOrderDetail set orderId=null where orderId=?
2022-06-10T09:15:43,190 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [1] as [BIGINT] - [45809]
2022-06-10T09:15:43,286 DEBUG [http-nio-8080-exec-82] o.h.e.j.s.SqlStatementLogger: update dbo.tblOrderDetail set orderId=? where id=?
2022-06-10T09:15:43,286 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [1] as [BIGINT] - [45809]
2022-06-10T09:15:43,286 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [2] as [BIGINT] - [117736]
2022-06-10T09:15:43,306 DEBUG [http-nio-8080-exec-82] o.h.e.j.s.SqlStatementLogger: update dbo.tblOrderDetail set orderId=? where id=?
2022-06-10T09:15:43,307 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [1] as [BIGINT] - [45809]
2022-06-10T09:15:43,307 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [2] as [BIGINT] - [117735]
2022-06-10T09:15:43,325 DEBUG [http-nio-8080-exec-82] o.h.e.j.s.SqlStatementLogger: update dbo.tblOrderDetail set orderId=? where id=?
2022-06-10T09:15:43,326 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [1] as [BIGINT] - [45809]
2022-06-10T09:15:43,326 TRACE [http-nio-8080-exec-82] o.h.t.d.s.BasicBinder: binding parameter [2] as [BIGINT] - [117770]
It goes through each detail, unsets the orderId, then resets the orderId. This is also part of the saveOrUpdate on LINE 190, because it happens before the next select Order.
Here is the orderDao.saveOrUpdate method
@Override
public OrderOld saveOrUpdate(OrderOld order) {
Session session = sessionFactoryKOMS.getCurrentSession();
if (order.getId() == null || order.getId().longValue() == 0L) {
Long id = (Long) session.save(order);
return session.find(OrderOld.class, id);
}
session.update(order);
return order;
}
Why is it doing this and how can I stop it?