Bug 313 : Change update() to support nested saves ... removing unattached detail beans.
Priority 
High
Reported Version 
 
Logged By 
Rob
Status 
Fixed
Fixed Version 
2.7.2
Assigned To 
 
Product 
Ebean - core
Duplicate Of 
 
Created 
02/07/2010
Updated 
02/07/2010
Type 
Bug
 
Attachments 
No attachments

Refer to:
http://groups.google.com/group/ebean/browse_thread/thread/4d2871ac9f8fe765

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();
        }
 
Rob 10 Nov 09:51
Fixed in HEAD

fixed in HEAD.

What this means is that the if you use server.update() ... and that cascades to a OneToMany (or ManyToMany) then Ebean will delete 'detail' beans that are no longer in the OneToMany.

woResponse

Upload a file