示例#1
0
  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());
  }