Beispiel #1
0
 private SimpleValue bindColumnToSimpleValue(
     Table table, Column column, Mapping mapping, boolean generatedIdentifier) {
   SimpleValue value = new SimpleValue(table);
   value.addColumn(column);
   value.setTypeName(guessAndAlignType(table, column, mapping, generatedIdentifier));
   return value;
 }
  public void /*test*/ AddNewProperty() {
    System.out.println("******************* testAddNewProperty ********************");
    PersistentClass userMapping = HibernateUtil.getClassMapping(User.class);

    Column column = new Column();
    column.setName("MOTTO");
    column.setNullable(false);
    column.setUnique(true);
    column.setSqlType("VARCHAR");
    userMapping.getTable().addColumn(column);

    SimpleValue value = new SimpleValue();
    value.setTable(userMapping.getTable());
    value.addColumn(column);
    value.setTypeName("string");

    Property prop = new Property();
    prop.setValue(value);
    prop.setName("motto");
    prop.setPropertyAccessorName("field");
    prop.setNodeName(prop.getName());
    userMapping.addProperty(prop);

    HibernateUtil.rebuildSessionFactory();

    ClassMetadata metadata = HibernateUtil.getClassMetadata(User.class);
    String[] propNames = metadata.getPropertyNames();
    boolean mottoFound = false;
    for (int i = 0; i < propNames.length; i++) {
      String propName = propNames[i];
      if (propName.equalsIgnoreCase("motto")) {
        mottoFound = true;
        break;
      }
    }

    assertTrue(mottoFound);
  }
  /**
   * 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;
  }
  @SuppressWarnings({"unchecked"})
  public void doSecondPass(Map persistentClasses) throws MappingException {
    PersistentClass referencedPersistentClass =
        (PersistentClass) persistentClasses.get(referencedEntityName);
    // TODO better error names
    if (referencedPersistentClass == null) {
      throw new AnnotationException("Unknown entity name: " + referencedEntityName);
    }
    if (!(referencedPersistentClass.getIdentifier() instanceof Component)) {
      throw new AssertionFailure(
          "Unexpected identifier type on the referenced entity when mapping a @MapsId: "
              + referencedEntityName);
    }
    Component referencedComponent = (Component) referencedPersistentClass.getIdentifier();
    Iterator<Property> properties = referencedComponent.getPropertyIterator();

    // prepare column name structure
    boolean isExplicitReference = true;
    Map<String, Ejb3JoinColumn> columnByReferencedName =
        new HashMap<String, Ejb3JoinColumn>(joinColumns.length);
    for (Ejb3JoinColumn joinColumn : joinColumns) {
      final String referencedColumnName = joinColumn.getReferencedColumn();
      if (referencedColumnName == null
          || BinderHelper.isEmptyAnnotationValue(referencedColumnName)) {
        break;
      }
      // JPA 2 requires referencedColumnNames to be case insensitive
      columnByReferencedName.put(referencedColumnName.toLowerCase(), joinColumn);
    }
    // try default column orientation
    int index = 0;
    if (columnByReferencedName.isEmpty()) {
      isExplicitReference = false;
      for (Ejb3JoinColumn joinColumn : joinColumns) {
        columnByReferencedName.put("" + index, joinColumn);
        index++;
      }
      index = 0;
    }

    while (properties.hasNext()) {
      Property referencedProperty = properties.next();
      if (referencedProperty.isComposite()) {
        throw new AssertionFailure(
            "Unexpected nested component on the referenced entity when mapping a @MapsId: "
                + referencedEntityName);
      } else {
        Property property = new Property();
        property.setName(referencedProperty.getName());
        property.setNodeName(referencedProperty.getNodeName());
        // FIXME set optional?
        // property.setOptional( property.isOptional() );
        property.setPersistentClass(component.getOwner());
        property.setPropertyAccessorName(referencedProperty.getPropertyAccessorName());
        SimpleValue value = new SimpleValue(mappings, component.getTable());
        property.setValue(value);
        final SimpleValue referencedValue = (SimpleValue) referencedProperty.getValue();
        value.setTypeName(referencedValue.getTypeName());
        value.setTypeParameters(referencedValue.getTypeParameters());
        final Iterator<Column> columns = referencedValue.getColumnIterator();

        if (joinColumns[0].isNameDeferred()) {
          joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns(
              referencedPersistentClass, columns, value);
        } else {
          // FIXME take care of Formula
          while (columns.hasNext()) {
            Column column = columns.next();
            final Ejb3JoinColumn joinColumn;
            String logicalColumnName = null;
            if (isExplicitReference) {
              final String columnName = column.getName();
              logicalColumnName =
                  mappings.getLogicalColumnName(columnName, referencedPersistentClass.getTable());
              // JPA 2 requires referencedColumnNames to be case insensitive
              joinColumn = columnByReferencedName.get(logicalColumnName.toLowerCase());
            } else {
              joinColumn = columnByReferencedName.get("" + index);
              index++;
            }
            if (joinColumn == null && !joinColumns[0].isNameDeferred()) {
              throw new AnnotationException(
                  isExplicitReference
                      ? "Unable to find column reference in the @MapsId mapping: "
                          + logicalColumnName
                      : "Implicit column reference in the @MapsId mapping fails, try to use explicit referenceColumnNames: "
                          + referencedEntityName);
            }
            final String columnName =
                joinColumn == null || joinColumn.isNameDeferred()
                    ? "tata_" + column.getName()
                    : joinColumn.getName();
            value.addColumn(new Column(columnName));
            column.setValue(value);
          }
        }
        component.addProperty(property);
      }
    }
  }
Beispiel #5
0
  /**
   * @param rc
   * @param processed
   * @param table
   * @param object
   */
  private Property bindOneToMany(
      PersistentClass rc, ForeignKey foreignKey, Set processed, Mapping mapping) {

    Table collectionTable = foreignKey.getTable();

    //		Collection collection = new org.hibernate.mapping.Set(rc); // MASTER TODO: allow overriding
    // collection type
    Collection collection =
        new org.hibernate.mapping.List(rc); // MASTER TODO: allow overriding collection type

    collection.setCollectionTable(collectionTable); // CHILD+

    boolean manyToMany = revengStrategy.isManyToManyTable(collectionTable);
    if (manyToMany) {
      // log.debug("Rev.eng said here is a many-to-many");
      // TODO: handle "the other side should influence the name"
    }

    if (manyToMany) {

      ManyToOne element = new ManyToOne(collection.getCollectionTable());
      // TODO: find the other foreignkey and choose the other side.
      Iterator foreignKeyIterator = foreignKey.getTable().getForeignKeyIterator();
      List keys = new ArrayList();
      while (foreignKeyIterator.hasNext()) {
        Object next = foreignKeyIterator.next();
        if (next != foreignKey) {
          keys.add(next);
        }
      }

      if (keys.size() > 1) {
        throw new JDBCBinderException(
            "more than one other foreign key to choose from!"); // todo: handle better ?
      }

      ForeignKey fk = (ForeignKey) keys.get(0);

      String tableToClassName = bindCollection(rc, foreignKey, fk, collection);

      element.setReferencedEntityName(tableToClassName);
      element.addColumn(fk.getColumn(0));
      collection.setElement(element);

    } else {
      String tableToClassName = bindCollection(rc, foreignKey, null, collection);

      OneToMany oneToMany = new OneToMany(collection.getOwner());

      oneToMany.setReferencedEntityName(tableToClassName); // Child
      mappings.addSecondPass(new JDBCCollectionSecondPass(mappings, collection));

      collection.setElement(oneToMany);
    }
    // bind keyvalue
    KeyValue referencedKeyValue;
    String propRef = collection.getReferencedPropertyName();
    if (propRef == null) {
      referencedKeyValue = collection.getOwner().getIdentifier();
    } else {
      referencedKeyValue = (KeyValue) collection.getOwner().getProperty(propRef).getValue();
    }

    SimpleValue keyValue = new DependantValue(collectionTable, referencedKeyValue);
    // keyValue.setForeignKeyName("none"); // Avoid creating the foreignkey
    // key.setCascadeDeleteEnabled( "cascade".equals( subnode.attributeValue("on-delete") ) );
    Iterator columnIterator = foreignKey.getColumnIterator();
    while (columnIterator.hasNext()) {
      Column fkcolumn = (Column) columnIterator.next();
      if (fkcolumn.getSqlTypeCode()
          != null) { // TODO: user defined foreign ref columns does not have a type set.
        guessAndAlignType(
            collectionTable,
            fkcolumn,
            mapping,
            false); // needed to ensure foreign key columns has same type as the "property" column.
      }
      keyValue.addColumn(fkcolumn);
    }

    collection.setKey(keyValue);

    mappings.addCollection(collection);

    return makeCollectionProperty(
        StringHelper.unqualify(collection.getRole()),
        true,
        rc.getTable(),
        foreignKey,
        collection,
        true);
    // return makeProperty(TableIdentifier.create( rc.getTable() ), StringHelper.unqualify(
    // collection.getRole() ), collection, true, true, true, "none", null); // TODO: cascade isn't
    // all by default

  }