I reproduced the issue. Looks like you are using enhanced beans.
Right now to handle the nested json update you need to:
- turn off cascade persist (programmatically)
- update the parent bean
- loop through the nested details and either save or update (determine if it is insert or update) based on a version property or id value
- delete any detail beans that you didn't save or update
So the relevant part of my test case code to do this was:
// ... generate the jsonString with the changes ...
Order updOrder = jsonContext.toBean(Order.class, jsonString);
Transaction t = server.beginTransaction();
try {
// turn of the cascading persist for the moment
t.setPersistCascade(false);
// force an update on the parent bean
t.log("-- stateless update of order ... ");
server.update(updOrder);
List<Integer> detailIds = new ArrayList<Integer>();
// loop through the detail beans... and insert or update
t.log("-- insert/update of order details ... ");
List<OrderDetail> details = updOrder.getDetails();
for (OrderDetail orderDetail : details) {
detailIds.add(orderDetail.getId());
if (orderDetail.getUpdtime() == null) {
// insert
server.save(orderDetail);
} else {
// force update
server.update(orderDetail);
}
}
// delete any orderDetails ... that where not in the list
String del = "delete from OrderDetail where
order.id=:orderId and id not in (:detailIds)";
Update<OrderDetail> deleteOtherDetails = server.createUpdate(OrderDetail.class, del);
deleteOtherDetails.setParameter("orderId", updOrder.getId());
deleteOtherDetails.setParameter("detailIds", detailIds);
t.log("-- deleting details that are not in list ");
deleteOtherDetails.execute();
t.commit();
} finally {
t.end();
}
... and the transaction log looks like...
txn[1008], 10:57:14.745, -- stateless update of order ...
txn[1008], 10:57:16.570, update o_order set status=?, order_date=?, ship_date=?, updtime=?, kcustomer_id=? where id=? and updtime=?
txn[1008], 10:57:27.038, Binding Update [o_order] set[status=SHIPPED, orderDate=2010-06-01, shipDate=null, updtime=2010-06-01 10:57:27.025, kcustomer_id=5, ] where[id=5, updtime=2010-06-01 10:57:14.647, ]
txn[1008], 10:57:27.040, Updated [Order] [5]
txn[1008], 10:57:27.041, -- insert/update of order details ...
txn[1008], 10:57:27.043, update o_order_detail set order_qty=?, ship_qty=?, unit_price=?, cretime=?, updtime=?, product_id=? where id=? and updtime=?
txn[1008], 10:57:27.044, Binding Update [o_order_detail] set[orderQty=5, shipQty=300, unitPrice=56.98, cretime=null, updtime=2010-06-01 10:57:27.043, product_id=1, ] where[id=7, updtime=2010-06-01 10:57:14.647, ]
txn[1008], 10:57:27.044, Updated [OrderDetail] [7]
txn[1008], 10:57:27.045, update o_order_detail set order_qty=?, ship_qty=?, unit_price=?, cretime=?, updtime=?, product_id=? where id=? and updtime=?
txn[1008], 10:57:27.046, Binding Update [o_order_detail] set[orderQty=3, shipQty=null, unitPrice=1.1, cretime=null, updtime=2010-06-01 10:57:27.045, product_id=2, ] where[id=8, updtime=2010-06-01 10:57:14.647, ]
txn[1008], 10:57:27.054, Updated [OrderDetail] [8]
txn[1008], 10:57:27.057, insert into o_order_detail (id, order_qty, ship_qty, unit_price, cretime, updtime, order_id, product_id) values (?,?,?,?,?,?,?,?)
txn[1008], 10:57:27.059, Binding Insert [o_order_detail] set[id=10, orderQty=899, shipQty=null, unitPrice=12.12, cretime=null, updtime=2010-06-01 10:57:27.058, order_id=null, product_id=1, ]
txn[1008], 10:57:27.061, Inserted [OrderDetail] [10]
txn[1008], 10:57:27.077, -- deleting details that are not in list
txn[1008], 10:57:27.107, delete from o_order_detail where order_id=? and id not in (?,?,?)
txn[1008], 10:57:27.124, Delete table[o_order_detail] rows[0] bind[5, 7, 8, null, ]
So that said... I'll have a look at this to see if we should get Ebean to do this for us when we cascade on the 'stateless bean update'.
Cheers, Rob.