public void delete(OpenJPAStateManager sm, JDBCStore store, RowManager rm) throws SQLException { if (field.getMappedBy() != null) return; // if nullable, null any existing inverse columns that refer to this obj ValueMapping elem = field.getElementMapping(); ColumnIO io = elem.getColumnIO(); ForeignKey fk = elem.getForeignKey(); if (!elem.getUseClassCriteria() && io.isAnyUpdatable(fk, true)) { assertInversable(); Row row = rm.getAllRows(fk.getTable(), Row.ACTION_UPDATE); row.setForeignKey(fk, io, null); row.whereForeignKey(fk, sm); rm.flushAllRows(row); return; } if (!sm.getLoaded().get(field.getIndex())) return; // update fk on each field value row ClassMapping rel = field.getElementMapping().getTypeMapping(); StoreContext ctx = store.getContext(); Collection objs = toCollection(sm.fetchObject(field.getIndex())); if (objs != null && !objs.isEmpty()) for (Iterator itr = objs.iterator(); itr.hasNext(); ) updateInverse(ctx, itr.next(), rel, rm, sm, 0); }
protected Joins join(Joins joins, ClassMapping elem) { ValueMapping vm = field.getElementMapping(); ForeignKey fk = vm.getForeignKey(elem); ClassMapping owner = field.getDefiningMapping(); while (fk.getPrimaryKeyTable() != owner.getTable()) { joins = owner.joinSuperclass(joins, false); owner = owner.getJoinablePCSuperclassMapping(); if (owner == null) throw new InternalException(); } return joins.joinRelation(field.getName(), fk, elem, vm.getSelectSubclasses(), true, true); }
/** This method updates the inverse columns of a 1-M related object with the given oid. */ private void updateInverse( StoreContext ctx, Object inverse, ClassMapping rel, RowManager rm, OpenJPAStateManager sm, int idx) throws SQLException { OpenJPAStateManager invsm = RelationStrategies.getStateManager(inverse, ctx); if (invsm == null) return; ValueMapping elem = field.getElementMapping(); ForeignKey fk = elem.getForeignKey(); ColumnIO io = elem.getColumnIO(); Column order = field.getOrderColumn(); int action; boolean writeable; boolean orderWriteable; if (invsm.isNew() && !invsm.isFlushed()) { // no need to null inverse columns of new instance if (sm == null || sm.isDeleted()) return; writeable = io.isAnyInsertable(fk, false); orderWriteable = _orderInsert; action = Row.ACTION_INSERT; } else if (invsm.isDeleted()) { // no need to null inverse columns of deleted instance if (invsm.isFlushed() || sm == null || !sm.isDeleted()) return; writeable = true; orderWriteable = false; action = Row.ACTION_DELETE; } else { if (sm != null && sm.isDeleted()) sm = null; writeable = io.isAnyUpdatable(fk, sm == null); orderWriteable = field.getOrderColumnIO().isUpdatable(order, sm == null); action = Row.ACTION_UPDATE; } if (!writeable && !orderWriteable) return; assertInversable(); // if this is an update, this might be the only mod to the row, so // make sure the where condition is set Row row = rm.getRow(fk.getTable(), action, invsm, true); if (action == Row.ACTION_UPDATE) row.wherePrimaryKey(invsm); // update the inverse pointer with our oid value if (writeable) row.setForeignKey(fk, io, sm); if (orderWriteable) row.setInt(order, idx); }
public void map(boolean adapt) { OpenJPAConfiguration conf = field.getRepository().getConfiguration(); boolean isNonDefaultMappingAllowed = field.getRepository().getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); FieldMapping mapped = field.getMappedByMapping(); // JPA 2.0 allows non-default mapping: Uni-/1-M/@JoinColumn ==> foreign key strategy // Bi-/1-M/@JoinColumn should result in exception if (!isNonDefaultMappingAllowed || mapped != null) { field.getValueInfo().assertNoSchemaComponents(field, !adapt); } field.getKeyMapping().getValueInfo().assertNoSchemaComponents(field.getKey(), !adapt); ValueMapping elem = field.getElementMapping(); if (elem.getTypeCode() != JavaTypes.PC || elem.isEmbeddedPC() || !elem.getTypeMapping().isMapped()) throw new MetaDataException(_loc.get("not-elem-relation", field)); // check for named inverse FieldMappingInfo finfo = field.getMappingInfo(); ValueMappingInfo vinfo = elem.getValueInfo(); boolean criteria = vinfo.getUseClassCriteria(); if (mapped != null) { mapped.resolve(mapped.MODE_META | mapped.MODE_MAPPING); if (!(mapped.getStrategy() instanceof RelationFieldStrategy || mapped.getHandler() instanceof UntypedPCValueHandler)) throw new MetaDataException(_loc.get("not-inv-relation", field, mapped)); vinfo.assertNoSchemaComponents(elem, !adapt); elem.setForeignKey(mapped.getForeignKey(field.getDefiningMapping())); elem.setColumns(mapped.getDefiningMapping().getPrimaryKeyColumns()); elem.setJoinDirection(ValueMapping.JOIN_EXPECTED_INVERSE); elem.setUseClassCriteria(criteria); ForeignKey fk = mapped.getForeignKey(); /** * Foreign key may be null if declared type of the mapped field is abstract and under * table-per-class inheritance strategy will have no mapped table. */ if (fk != null) { field.setOrderColumn(finfo.getOrderColumn(field, fk.getTable(), adapt)); field.setOrderColumnIO(finfo.getColumnIO()); } return; } else { if (field.getValueInfo().getColumns().size() > 0 && field.getAccessType() == FieldMetaData.ONE_TO_MANY) { _uni1MFK = true; } } // map inverse foreign key in related table ForeignKey fk = vinfo.getInverseTypeJoin(elem, field.getName(), adapt); if (_uni1MFK) { Column[] locals = fk.getColumns(); for (int i = 0; i < locals.length; i++) locals[i].setUni1MFK(true); } elem.setForeignKey(fk); elem.setColumnIO(vinfo.getColumnIO()); elem.setColumns(elem.getTypeMapping().getPrimaryKeyColumns()); elem.setJoinDirection(ValueMapping.JOIN_EXPECTED_INVERSE); elem.setUseClassCriteria(criteria); elem.mapConstraints(field.getName(), adapt); field.setOrderColumn(finfo.getOrderColumn(field, fk.getTable(), adapt)); field.setOrderColumnIO(finfo.getColumnIO()); }