public void update()

in openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationRelationMapTableFieldStrategy.java [327:494]


    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, rm, map, store);
            return;
        }

        ValueMapping key = field.getKeyMapping();
        ValueMapping val = field.getElementMapping();
        StoreContext ctx = store.getContext();
        OpenJPAStateManager keysm, 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;
                Object mval = map.get(mkey);
                if (mval == null) {
                    Set<Map.Entry> entries = map.entrySet();
                    for (Map.Entry entry : entries) {
                        if (entry.getKey().equals(mkey))
                            mval = entry.getValue();
                    }
                }
                if (mval == null)
                    continue;
                keysm = RelationStrategies.getStateManager(mkey, ctx);
                valsm = RelationStrategies.getStateManager(mval, ctx);
                key.whereForeignKey(changeRow, keysm);
                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);
                    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 pc : rem) {
                if (field.isUni1ToMFK()) {
                    updateSetNull(sm, rm, pc);
                }
                else {
                    keysm = RelationStrategies.getStateManager(pc, ctx);
                    key.whereForeignKey(delRow, keysm);
                    rm.flushSecondaryRow(delRow);
                }
            }
            if (!canChange && !change.isEmpty()) {
                for (Object pc : change) {
                    if (field.isUni1ToMFK()) {
                        updateSetNull(sm, rm, pc);
                    }
                    else {
                        keysm = RelationStrategies.getStateManager(pc, ctx);
                        key.whereForeignKey(delRow, keysm);
                        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;
                Object mval = map.get(mkey);
                if (mval == null) {
                    Set<Map.Entry> entries = map.entrySet();
                    for (Map.Entry entry : entries) {
                        if (entry.getKey().equals(mkey))
                            mval = entry.getValue();
                    }
                }
                if (mval == null)
                    continue;
                keysm = RelationStrategies.getStateManager(mkey, ctx);
                valsm = RelationStrategies.getStateManager(mval, ctx);
                if (field.isUni1ToMFK()) {
                    addRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
                            Row.ACTION_UPDATE, valsm, true);
                    addRow.wherePrimaryKey(valsm);
                    key.setForeignKey(addRow, keysm);
                    val.setForeignKey(addRow, sm);
                }
                else {
                    key.setForeignKey(addRow, keysm);
                    val.setForeignKey(addRow, valsm);
                    rm.flushSecondaryRow(addRow);
                }
            }
            if (!canChange && !change.isEmpty()) {
                for (Object o : change) {
                    mkey = o;
                    Object mval = map.get(mkey);
                    if (mval == null) {
                        Set<Map.Entry> entries = map.entrySet();
                        for (Map.Entry entry : entries) {
                            if (entry.getKey().equals(mkey))
                                mval = entry.getValue();
                        }
                    }
                    if (mval == null)
                        continue;
                    keysm = RelationStrategies.getStateManager(mkey, ctx);
                    valsm = RelationStrategies.getStateManager(mval, ctx);
                    if (field.isUni1ToMFK()) {
                        addRow = rm.getRow(field.getElementMapping().getDeclaredTypeMapping().getTable(),
                                Row.ACTION_UPDATE, valsm, true);
                        addRow.wherePrimaryKey(valsm);
                        key.setForeignKey(addRow, keysm);
                        val.setForeignKey(addRow, sm);
                    }
                    else {
                        key.setForeignKey(addRow, keysm);
                        val.setForeignKey(addRow, valsm);
                        rm.flushSecondaryRow(addRow);
                    }
                }
            }
        }
    }