public void appendTo(Select sel, ExpContext ctx, ExpState state, SQLBuffer sql, int index) { if (!(_map instanceof PCPath)) throw new UnsupportedOperationException(); if (!(_key instanceof Const)) throw new UnsupportedOperationException(); GetMapValueExpState gstate = (GetMapValueExpState) state; PCPath map = (PCPath) _map; Object key = ((Const) _key).getValue(ctx, gstate.keyState); FieldMapping field = map.getFieldMapping(gstate.mapState); if (!(field.getStrategy() instanceof LRSMapFieldStrategy)) throw new UnsupportedOperationException(); LRSMapFieldStrategy strat = (LRSMapFieldStrategy) field.getStrategy(); ClassMapping[] clss = strat.getIndependentValueMappings(true); if (clss != null && clss.length > 1) throw RelationStrategies.unjoinable(field); ClassMapping cls = (clss == null || clss.length == 0) ? null : clss[0]; ForeignKey fk = strat.getJoinForeignKey(cls); // manually create a subselect for the Map's value sql.append("(SELECT "); Column[] values = field.getElementMapping().getColumns(); for (int i = 0; i < values.length; i++) { if (i > 0) sql.append(", "); sql.append(values[i].getTable()).append(".").append(values[i]); } sql.append(" FROM ").append(values[0].getTable()); sql.append(" WHERE "); // add in the joins ContainerFieldStrategy.appendUnaliasedJoin( sql, sel, null, ctx.store.getDBDictionary(), field, fk); sql.append(" AND "); key = strat.toKeyDataStoreValue(key, ctx.store); Column[] cols = strat.getKeyColumns(cls); Object[] vals = (cols.length == 1) ? null : (Object[]) key; for (int i = 0; i < cols.length; i++) { sql.append(cols[i].getTable()).append(".").append(cols[i]); if (vals == null) sql.append((key == null) ? " IS " : " = ").appendValue(key, cols[i]); else sql.append((vals[i] == null) ? " IS " : " = ").appendValue(vals[i], cols[i]); } sql.append(")"); }
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()); }