public void update()

in openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/HandlerRelationMapTableFieldStrategy.java [277:417]


    public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm)
        throws SQLException {
        if (field.getMappedBy() != null && !field.isBiMTo1JT())
            return;

        Map map = (Map) sm.fetchObject(field.getIndex());
        ChangeTracker ct = null;
        if (map instanceof Proxy) {
            Proxy proxy = (Proxy) map;
            if (Proxies.isOwner(proxy, sm, field.getIndex()))
                ct = proxy.getChangeTracker();
        }

        // if no fine-grained change tracking then just delete and reinsert
        if (ct == null || !ct.isTracking()) {
            delete(sm, store, rm);
            insert(sm, store, rm, map);
            return;
        }

        ValueMapping key = field.getKeyMapping();
        ValueMapping val = field.getElementMapping();
        StoreContext ctx = store.getContext();
        OpenJPAStateManager valsm;

        // update the changes; note that we have to model changes as
        // delete-then-insert if we have a foreign key action, because
        // secondary row updates aren't part of the constraint graph
        Collection change = ct.getChanged();
        boolean canChange = val.getForeignKey().isLogical();
        Object mkey;
        if (canChange && !change.isEmpty()) {
            Row changeRow = null;
            if (!field.isUni1ToMFK()) {
                changeRow = rm.getSecondaryRow(field.getTable(),
                    Row.ACTION_UPDATE);
                changeRow.whereForeignKey(field.getJoinForeignKey(), sm);
            }

            for (Object o : change) {
                mkey = o;
                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
                if (field.isUni1ToMFK()) {
                    changeRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
                            Row.ACTION_UPDATE, valsm, true);
                    changeRow.wherePrimaryKey(valsm);
                    val.setForeignKey(changeRow, sm);
                }
                else {
                    val.setForeignKey(changeRow, valsm);
                }

                HandlerStrategies.where(key, mkey, store, changeRow, _kcols);
                if (!field.isUni1ToMFK())
                    rm.flushSecondaryRow(changeRow);
            }
        }

        // delete the removes
        Collection rem = ct.getRemoved();
        if (!rem.isEmpty() || (!canChange && !change.isEmpty())) {
            Row delRow = null;
            if (!field.isUni1ToMFK()) {
                delRow = rm.getSecondaryRow(field.getTable(),
                    Row.ACTION_DELETE);
                delRow.whereForeignKey(field.getJoinForeignKey(), sm);
            }
            for (Object value : rem) {
                mkey = value;
                if (field.isUni1ToMFK()) {
                    updateSetNull(sm, mkey, store, rm);
                }
                else {
                    HandlerStrategies.where(key, mkey, store, delRow, _kcols);
                    rm.flushSecondaryRow(delRow);
                }
            }
            if (!canChange && !change.isEmpty()) {
                for (Object o : change) {
                    mkey = o;
                    if (field.isUni1ToMFK()) {
                        updateSetNull(sm, mkey, store, rm);
                    }
                    else {
                        HandlerStrategies.where(key, mkey, store, delRow, _kcols);
                        rm.flushSecondaryRow(delRow);
                    }
                }
            }
        }

        // insert the adds
        Collection add = ct.getAdded();
        if (!add.isEmpty() || (!canChange && !change.isEmpty())) {
            Row addRow = null;
            if (!field.isUni1ToMFK()) {
                addRow = rm.getSecondaryRow(field.getTable(),
                        Row.ACTION_INSERT);
                addRow.setForeignKey(field.getJoinForeignKey(),
                        field.getJoinColumnIO(), sm);
            }
            for (Object value : add) {
                mkey = value;
                valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
                if (field.isUni1ToMFK()) {
                    addRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
                            Row.ACTION_UPDATE, valsm, true);
                    addRow.wherePrimaryKey(valsm);
                    val.setForeignKey(addRow, sm);
                }
                else {
                    val.setForeignKey(addRow, valsm);
                }

                HandlerStrategies.set(key, mkey, store, addRow, _kcols,
                        _kio, true);
                if (!field.isUni1ToMFK())
                    rm.flushSecondaryRow(addRow);
            }
            if (!canChange && !change.isEmpty()) {
                for (Object o : change) {
                    mkey = o;
                    valsm = RelationStrategies.getStateManager(map.get(mkey), ctx);
                    if (field.isUni1ToMFK()) {
                        addRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
                                Row.ACTION_UPDATE, valsm, true);
                        addRow.wherePrimaryKey(valsm);
                        val.setForeignKey(addRow, sm);
                    }
                    else {
                        val.setForeignKey(addRow, valsm);
                    }

                    HandlerStrategies.set(key, mkey, store, addRow, _kcols,
                            _kio, true);
                    if (!field.isUni1ToMFK())
                        rm.flushSecondaryRow(addRow);
                }
            }
        }
    }