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);
}
}
}
}