Exemplo n.º 1
0
 /** Shallow copy, the value is not copied */
 protected Object clone() {
   Column copy = new Column();
   copy.setLength(length);
   copy.setScale(scale);
   copy.setValue(value);
   copy.setTypeIndex(typeIndex);
   copy.setName(getQuotedName());
   copy.setNullable(nullable);
   copy.setPrecision(precision);
   copy.setUnique(unique);
   copy.setSqlType(sqlType);
   copy.setSqlTypeCode(sqlTypeCode);
   copy.uniqueInteger = uniqueInteger; // usually useless
   copy.setCheckConstraint(checkConstraint);
   copy.setComment(comment);
   copy.setDefaultValue(defaultValue);
   copy.setCustomRead(customRead);
   copy.setCustomWrite(customWrite);
   return copy;
 }
Exemplo n.º 2
0
  /**
   * Builds the <code>Join</code> instance for the mapped by side of a <i>OneToOne</i> association
   * using a join tables.
   *
   * <p>Note:<br>
   *
   * <ul>
   *   <li>From the mappedBy side we should not create the PK nor the FK, this is handled from the
   *       other side.
   *   <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</i>.
   */
  private Join buildJoinFromMappedBySide(
      PersistentClass persistentClass, Property otherSideProperty, Join originalJoin) {
    Join join = new Join();
    join.setPersistentClass(persistentClass);

    // no check constraints available on joins
    join.setTable(originalJoin.getTable());
    join.setInverse(true);
    SimpleValue key =
        new DependantValue(mappings, join.getTable(), persistentClass.getIdentifier());
    // TODO support @ForeignKey
    join.setKey(key);
    join.setSequentialSelect(false);
    // TODO support for inverse and optional
    join.setOptional(true); // perhaps not quite per-spec, but a Good Thing anyway
    key.setCascadeDeleteEnabled(false);
    Iterator mappedByColumns = otherSideProperty.getValue().getColumnIterator();
    while (mappedByColumns.hasNext()) {
      Column column = (Column) mappedByColumns.next();
      Column copy = new Column();
      copy.setLength(column.getLength());
      copy.setScale(column.getScale());
      copy.setValue(key);
      copy.setName(column.getQuotedName());
      copy.setNullable(column.isNullable());
      copy.setPrecision(column.getPrecision());
      copy.setUnique(column.isUnique());
      copy.setSqlType(column.getSqlType());
      copy.setCheckConstraint(column.getCheckConstraint());
      copy.setComment(column.getComment());
      copy.setDefaultValue(column.getDefaultValue());
      key.addColumn(copy);
    }
    persistentClass.addJoin(join);
    return join;
  }
  public static void processBasicColumns(
      MetaDataDialect metaDataDialect,
      ReverseEngineeringStrategy revengStrategy,
      String defaultSchema,
      String defaultCatalog,
      Table table,
      ProgressListener progress) {

    String qualify =
        TableNameQualifier.qualify(table.getCatalog(), table.getSchema(), table.getName());
    Iterator<?> columnIterator = null;

    try {
      Map<?, ?> columnRs = null;
      log.debug("Finding columns for " + qualify);
      progress.startSubTask("Finding columns for " + qualify);
      columnIterator =
          metaDataDialect.getColumns(
              getCatalogForDBLookup(table.getCatalog(), defaultCatalog),
              getSchemaForDBLookup(table.getSchema(), defaultSchema),
              table.getName(),
              null);
      // dumpHeader(columnRs);
      while (columnIterator.hasNext()) {
        // dumpRow(columnRs);
        columnRs = (Map<?, ?>) columnIterator.next();
        String tableName = (String) columnRs.get("TABLE_NAME");
        int sqlType = ((Integer) columnRs.get("DATA_TYPE")).intValue();
        // String sqlTypeName = (String) columnRs.get("TYPE_NAME");
        String columnName = (String) columnRs.get("COLUMN_NAME");
        String comment = (String) columnRs.get("REMARKS");

        TableIdentifier ti =
            RevEngUtils.createTableIdentifier(table, defaultCatalog, defaultSchema);
        if (revengStrategy.excludeColumn(ti, columnName)) {
          log.debug("Column " + ti + "." + columnName + " excluded by strategy");
          continue;
        }
        if (!tableName.equals(table.getName())) {
          log.debug(
              "Table name "
                  + tableName
                  + " does not match requested "
                  + table.getName()
                  + ". Ignoring column "
                  + columnName
                  + " since it either is invalid or a duplicate");
          continue;
        }

        // String columnDefaultValue = columnRs.getString("COLUMN_DEF"); TODO: only read if have a
        // way to avoid issues with clobs/lobs and similar
        int dbNullability = ((Integer) columnRs.get("NULLABLE")).intValue();
        boolean isNullable = true;
        switch (dbNullability) {
          case DatabaseMetaData.columnNullable:
          case DatabaseMetaData.columnNullableUnknown:
            isNullable = true;
            break;
          case DatabaseMetaData.columnNoNulls:
            isNullable = false;
            break;
          default:
            isNullable = true;
        }

        int size = ((Integer) columnRs.get("COLUMN_SIZE")).intValue();
        int decimalDigits = ((Integer) columnRs.get("DECIMAL_DIGITS")).intValue();

        Column column = new Column();
        column.setName(quote(columnName, metaDataDialect));
        Column existing = table.getColumn(column);
        if (existing != null) {
          // TODO: should we just pick it up and fill it up with whatever we get from the db instead
          // ?
          throw new JDBCBinderException(column + " already exists in " + qualify);
        }

        // TODO: column.setSqlType(sqlTypeName); //this does not work 'cos the
        // precision/scale/length are not retured in TYPE_NAME
        // column.setSqlType(sqlTypeName);
        column.setComment(comment);
        column.setSqlTypeCode(new Integer(sqlType));
        if (intBounds(size)) {
          if (JDBCToHibernateTypeHelper.typeHasLength(sqlType)) {
            column.setLength(size);
          }
          if (JDBCToHibernateTypeHelper.typeHasScaleAndPrecision(sqlType)) {
            column.setPrecision(size);
          }
        }
        if (intBounds(decimalDigits)) {
          if (JDBCToHibernateTypeHelper.typeHasScaleAndPrecision(sqlType)) {
            column.setScale(decimalDigits);
          }
        }

        column.setNullable(isNullable);

        // columnDefaultValue is useless for Hibernate
        // isIndexed  (available via Indexes)
        // unique - detected when getting indexes
        // isPk - detected when finding primary keys

        table.addColumn(column);
      }
    } finally {

      if (columnIterator != null) {
        try {
          metaDataDialect.close(columnIterator);
        } catch (JDBCException se) {
          log.warn("Exception while closing iterator for column meta data", se);
        }
      }
    }
  }
Exemplo n.º 4
0
  // TODO refactor this code, there is a lot of duplication in this method
  public void doSecondPass(Map persistentClasses) throws MappingException {
    org.hibernate.mapping.OneToOne value =
        new org.hibernate.mapping.OneToOne(
            mappings, propertyHolder.getTable(), propertyHolder.getPersistentClass());
    final String propertyName = inferredData.getPropertyName();
    value.setPropertyName(propertyName);
    String referencedEntityName =
        ToOneBinder.getReferenceEntityName(inferredData, targetEntity, mappings);
    value.setReferencedEntityName(referencedEntityName);
    AnnotationBinder.defineFetchingStrategy(value, inferredData.getProperty());
    // value.setFetchMode( fetchMode );
    value.setCascadeDeleteEnabled(cascadeOnDelete);
    // value.setLazy( fetchMode != FetchMode.JOIN );

    if (!optional) value.setConstrained(true);
    value.setForeignKeyType(
        value.isConstrained()
            ? ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT
            : ForeignKeyDirection.FOREIGN_KEY_TO_PARENT);
    PropertyBinder binder = new PropertyBinder();
    binder.setName(propertyName);
    binder.setValue(value);
    binder.setCascade(cascadeStrategy);
    binder.setAccessType(inferredData.getDefaultAccess());
    Property prop = binder.makeProperty();
    if (BinderHelper.isEmptyAnnotationValue(mappedBy)) {
      /*
       * we need to check if the columns are in the right order
       * if not, then we need to create a many to one and formula
       * but actually, since entities linked by a one to one need
       * to share the same composite id class, this cannot happen in hibernate
       */
      boolean rightOrder = true;

      if (rightOrder) {
        String path = StringHelper.qualify(propertyHolder.getPath(), propertyName);
        (new ToOneFkSecondPass(
                value,
                joinColumns,
                !optional, // cannot have nullabe and unique on certain DBs
                propertyHolder.getEntityOwnerClassName(),
                path,
                mappings))
            .doSecondPass(persistentClasses);
        // no column associated since its a one to one
        propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
      } else {
        // this is a many to one with Formula

      }
    } else {
      PersistentClass otherSide =
          (PersistentClass) persistentClasses.get(value.getReferencedEntityName());
      Property otherSideProperty;
      try {
        if (otherSide == null) {
          throw new MappingException("Unable to find entity: " + value.getReferencedEntityName());
        }
        otherSideProperty = BinderHelper.findPropertyByName(otherSide, mappedBy);
      } catch (MappingException e) {
        throw new AnnotationException(
            "Unknown mappedBy in: "
                + StringHelper.qualify(ownerEntity, ownerProperty)
                + ", referenced property unknown: "
                + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
      }
      if (otherSideProperty == null) {
        throw new AnnotationException(
            "Unknown mappedBy in: "
                + StringHelper.qualify(ownerEntity, ownerProperty)
                + ", referenced property unknown: "
                + StringHelper.qualify(value.getReferencedEntityName(), mappedBy));
      }
      if (otherSideProperty.getValue() instanceof OneToOne) {
        propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
      } else if (otherSideProperty.getValue() instanceof ManyToOne) {
        Iterator it = otherSide.getJoinIterator();
        Join otherSideJoin = null;
        while (it.hasNext()) {
          Join otherSideJoinValue = (Join) it.next();
          if (otherSideJoinValue.containsProperty(otherSideProperty)) {
            otherSideJoin = otherSideJoinValue;
            break;
          }
        }
        if (otherSideJoin != null) {
          // @OneToOne @JoinTable
          Join mappedByJoin =
              buildJoinFromMappedBySide(
                  (PersistentClass) persistentClasses.get(ownerEntity),
                  otherSideProperty,
                  otherSideJoin);
          ManyToOne manyToOne = new ManyToOne(mappings, mappedByJoin.getTable());
          // FIXME use ignore not found here
          manyToOne.setIgnoreNotFound(ignoreNotFound);
          manyToOne.setCascadeDeleteEnabled(value.isCascadeDeleteEnabled());
          manyToOne.setEmbedded(value.isEmbedded());
          manyToOne.setFetchMode(value.getFetchMode());
          manyToOne.setLazy(value.isLazy());
          manyToOne.setReferencedEntityName(value.getReferencedEntityName());
          manyToOne.setUnwrapProxy(value.isUnwrapProxy());
          prop.setValue(manyToOne);
          Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator();
          while (otherSideJoinKeyColumns.hasNext()) {
            Column column = (Column) otherSideJoinKeyColumns.next();
            Column copy = new Column();
            copy.setLength(column.getLength());
            copy.setScale(column.getScale());
            copy.setValue(manyToOne);
            copy.setName(column.getQuotedName());
            copy.setNullable(column.isNullable());
            copy.setPrecision(column.getPrecision());
            copy.setUnique(column.isUnique());
            copy.setSqlType(column.getSqlType());
            copy.setCheckConstraint(column.getCheckConstraint());
            copy.setComment(column.getComment());
            copy.setDefaultValue(column.getDefaultValue());
            manyToOne.addColumn(copy);
          }
          mappedByJoin.addProperty(prop);
        } else {
          propertyHolder.addProperty(prop, inferredData.getDeclaringClass());
        }

        value.setReferencedPropertyName(mappedBy);

        String propertyRef = value.getReferencedPropertyName();
        if (propertyRef != null) {
          mappings.addUniquePropertyReference(value.getReferencedEntityName(), propertyRef);
        }
      } else {
        throw new AnnotationException(
            "Referenced property not a (One|Many)ToOne: "
                + StringHelper.qualify(otherSide.getEntityName(), mappedBy)
                + " in mappedBy of "
                + StringHelper.qualify(ownerEntity, ownerProperty));
      }
    }
    ForeignKey fk = inferredData.getProperty().getAnnotation(ForeignKey.class);
    String fkName = fk != null ? fk.name() : "";
    if (!BinderHelper.isEmptyAnnotationValue(fkName)) value.setForeignKeyName(fkName);
  }