### Eclipse Workspace Patch 1.0 #P p2j4011a Index: src/com/goldencode/p2j/persist/orm/BaseRecord.java =================================================================== --- src/com/goldencode/p2j/persist/orm/BaseRecord.java (revision 2332) +++ src/com/goldencode/p2j/persist/orm/BaseRecord.java (working copy) @@ -682,22 +682,24 @@ * the full transaction block, and a positive number represents that number of nested * sub-transactions. */ - void rollback(Session session, int txLevel) + List rollback(Session session, int txLevel) { if (changeSet == null) { // this should not happen; we should only get this call if this record had at least one change // during an application transaction - return; + return null; } - changeSet.rollback(session, txLevel, this); + List actions = changeSet.rollback(session, txLevel, this); // discard the change set after rollback of the full transaction if (txLevel == 0) { changeSet = null; } + + return actions; } /** Index: src/com/goldencode/p2j/persist/orm/ChangeSet.java =================================================================== --- src/com/goldencode/p2j/persist/orm/ChangeSet.java (revision 2332) +++ src/com/goldencode/p2j/persist/orm/ChangeSet.java (working copy) @@ -66,6 +66,8 @@ import java.util.*; import java.util.logging.*; + +import com.goldencode.p2j.persist.PersistenceException; import com.goldencode.p2j.util.*; /** @@ -215,12 +217,12 @@ * @param dmo * Record to be rolled back. */ - void rollback(Session session, int txLevel, BaseRecord dmo) + List rollback(Session session, int txLevel, BaseRecord dmo) { if (changes == null || txLevel < outer || txLevel > inner) { // TODO: what is appropriate here? - return; + return null; } // live data to be updated by rollback @@ -287,9 +289,13 @@ for (int j = touched.nextSetBit(0); j >= 0; j = touched.nextSetBit(j + 1)) { data[j] = baseline[j]; + + dmo.setDatum(j, data[j]); } } + List rollbackActions = new LinkedList<>(); + // roll back state changed by events for (int i = inner; i >= txLevel; i--) { @@ -307,12 +313,33 @@ if ((next & Event.UPDATE) == Event.UPDATE) { - // TODO: is this needed? + rollbackActions.add(() -> + { + try + { + session.save(dmo, false); + } + catch (PersistenceException e) + { + throw new RuntimeException(e); + } + }); } if ((next & Event.INSERT) == Event.INSERT) { dmo.updateState(DmoState.NEW, true); + rollbackActions.add(() -> + { + try + { + session.save(dmo, false); + } + catch (PersistenceException e) + { + throw new RuntimeException(e); + } + }); } // handle create and/or delete @@ -335,6 +362,8 @@ // events have been rolled back; clear the flags events[i] = Event.NONE; } + + return rollbackActions.isEmpty() ? null : rollbackActions; } /** Index: src/com/goldencode/p2j/persist/orm/SavepointManager.java =================================================================== --- src/com/goldencode/p2j/persist/orm/SavepointManager.java (revision 2332) +++ src/com/goldencode/p2j/persist/orm/SavepointManager.java (working copy) @@ -292,7 +292,7 @@ if (session != null) { // mark all tracked, undoable records as STALE - endingBlock.rollback(session); + List rollbackActions = endingBlock.rollback(session); // the active block is now the parent block (if any); roll up all tracked // information for the ending block to it @@ -307,6 +307,14 @@ { session.rollbackSavepoint(endingBlock.savepoint); } + + if (rollbackActions != null) + { + for (Runnable action : rollbackActions) + { + action.run(); + } + } } } } @@ -633,11 +641,16 @@ /** * Roll back changes to undoable records and activate redoable actions for NO-UNDO records. */ - void rollback(Session session) + List rollback(Session session) { + List actions = new LinkedList<>(); for (BaseRecord dmo : changed) { - dmo.rollback(session, txLevel); + List dmoActions = dmo.rollback(session, txLevel); + if (dmoActions != null) + { + actions.addAll(dmoActions); + } } int redoSize = redoable.size(); @@ -650,6 +663,8 @@ redoable.get(i).setActive(); } } + + return actions.isEmpty() ? null : actions; } /**