@Deprecated
  public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) {
    final Type type = property.getValue().getType();

    // we need to dirty check collections, since they can cause an owner
    // version number increment

    // we need to dirty check many-to-ones with not-found="ignore" in order
    // to update the cache (not the database), since in this case a null
    // entity reference can lose information

    boolean alwaysDirtyCheck =
        type.isAssociationType() && ((AssociationType) type).isAlwaysDirtyChecked();

    return new StandardProperty(
        property.getName(),
        type,
        lazyAvailable && property.isLazy(),
        property.isInsertable(),
        property.isUpdateable(),
        property.getValueGenerationStrategy(),
        property.isOptional(),
        alwaysDirtyCheck || property.isUpdateable(),
        property.isOptimisticLocked(),
        property.getCascadeStyle(),
        property.getValue().getFetchMode());
  }
 protected void applyCacheSettings(Configuration configuration) {
   if (getCacheConcurrencyStrategy() != null) {
     Iterator itr = configuration.getClassMappings();
     while (itr.hasNext()) {
       PersistentClass clazz = (PersistentClass) itr.next();
       Iterator props = clazz.getPropertyClosureIterator();
       boolean hasLob = false;
       while (props.hasNext()) {
         Property prop = (Property) props.next();
         if (prop.getValue().isSimpleValue()) {
           String type = ((SimpleValue) prop.getValue()).getTypeName();
           if ("blob".equals(type) || "clob".equals(type)) {
             hasLob = true;
           }
           if (Blob.class.getName().equals(type) || Clob.class.getName().equals(type)) {
             hasLob = true;
           }
         }
       }
       if (!hasLob && !clazz.isInherited() && overrideCacheStrategy()) {
         configuration.setCacheConcurrencyStrategy(
             clazz.getEntityName(), getCacheConcurrencyStrategy());
       }
     }
     itr = configuration.getCollectionMappings();
     while (itr.hasNext()) {
       Collection coll = (Collection) itr.next();
       configuration.setCollectionCacheConcurrencyStrategy(
           coll.getRole(), getCacheConcurrencyStrategy());
     }
   }
 }
  /**
   * Generates a VersionProperty representation for an entity mapping given its version mapping
   * Property.
   *
   * @param property The version mapping Property.
   * @param lazyAvailable Is property lazy loading currently available.
   * @return The appropriate VersionProperty definition.
   */
  public static VersionProperty buildVersionProperty(
      EntityPersister persister,
      SessionFactoryImplementor sessionFactory,
      int attributeNumber,
      Property property,
      boolean lazyAvailable) {
    String mappedUnsavedValue = ((KeyValue) property.getValue()).getNullValue();

    VersionValue unsavedValue =
        UnsavedValueFactory.getUnsavedVersionValue(
            mappedUnsavedValue,
            getGetter(property),
            (VersionType) property.getType(),
            getConstructor(property.getPersistentClass()));

    boolean lazy = lazyAvailable && property.isLazy();

    return new VersionProperty(
        persister,
        sessionFactory,
        attributeNumber,
        property.getName(),
        property.getValue().getType(),
        new BaselineAttributeInformation.Builder()
            .setLazy(lazy)
            .setInsertable(property.isInsertable())
            .setUpdateable(property.isUpdateable())
            .setValueGenerationStrategy(property.getValueGenerationStrategy())
            .setNullable(property.isOptional())
            .setDirtyCheckable(property.isUpdateable() && !lazy)
            .setVersionable(property.isOptimisticLocked())
            .setCascadeStyle(property.getCascadeStyle())
            .createInformation(),
        unsavedValue);
  }
  protected boolean isRequiredInConstructor(Property field) {
    if (hasMetaAttribute(field, "default-value")) {
      return false;
    }
    if (field.getValue() != null) {
      if (!field.isOptional()
          && (field.getValueGenerationStrategy() == null
              || field
                  .getValueGenerationStrategy()
                  .getGenerationTiming()
                  .equals(GenerationTiming.NEVER))) {
        return true;
      } else if (field.getValue() instanceof Component) {
        Component c = (Component) field.getValue();
        Iterator<?> it = c.getPropertyIterator();
        while (it.hasNext()) {
          Property prop = (Property) it.next();
          if (isRequiredInConstructor(prop)) {
            return true;
          }
        }
      }
    }

    return false;
  }
Example #5
0
  private void buildSessionFactory(String[] files) throws Exception {

    if (getSessions() != null) getSessions().close();

    try {

      setCfg(new Configuration());

      cfg.addProperties(getExtraProperties());

      if (recreateSchema()) {
        cfg.setProperty(Environment.HBM2DDL_AUTO, "create-drop");
      }

      for (int i = 0; i < files.length; i++) {
        if (!files[i].startsWith("net/")) files[i] = getBaseForMappings() + files[i];
        getCfg().addResource(files[i], TestCase.class.getClassLoader());
      }

      setDialect(Dialect.getDialect());

      configure(cfg);

      if (getCacheConcurrencyStrategy() != null) {

        Iterator iter = cfg.getClassMappings();
        while (iter.hasNext()) {
          PersistentClass clazz = (PersistentClass) iter.next();
          Iterator props = clazz.getPropertyClosureIterator();
          boolean hasLob = false;
          while (props.hasNext()) {
            Property prop = (Property) props.next();
            if (prop.getValue().isSimpleValue()) {
              String type = ((SimpleValue) prop.getValue()).getTypeName();
              if ("blob".equals(type) || "clob".equals(type)) hasLob = true;
              if (Blob.class.getName().equals(type) || Clob.class.getName().equals(type))
                hasLob = true;
            }
          }
          if (!hasLob && !clazz.isInherited() && overrideCacheStrategy()) {
            cfg.setCacheConcurrencyStrategy(clazz.getEntityName(), getCacheConcurrencyStrategy());
          }
        }

        iter = cfg.getCollectionMappings();
        while (iter.hasNext()) {
          Collection coll = (Collection) iter.next();
          cfg.setCollectionCacheConcurrencyStrategy(coll.getRole(), getCacheConcurrencyStrategy());
        }
      }

      setSessions(getCfg().buildSessionFactory(/*new TestInterceptor()*/ ));

      afterSessionFactoryBuilt();
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
  }
 private void mapPropertyToIndex(Property prop, int i) {
   propertyIndexes.put(prop.getName(), i);
   if (prop.getValue() instanceof Component) {
     Iterator iter = ((Component) prop.getValue()).getPropertyIterator();
     while (iter.hasNext()) {
       Property subprop = (Property) iter.next();
       propertyIndexes.put(prop.getName() + '.' + subprop.getName(), i);
     }
   }
 }
 private ValueInclusion determineUpdateValueGenerationType(
     Property mappingProperty, NonIdentifierAttribute runtimeProperty) {
   if (isUpdateGenerated(runtimeProperty)) {
     return ValueInclusion.FULL;
   } else if (mappingProperty.getValue() instanceof Component) {
     if (hasPartialUpdateComponentGeneration((Component) mappingProperty.getValue())) {
       return ValueInclusion.PARTIAL;
     }
   }
   return ValueInclusion.NONE;
 }
 private ValueInclusion determineInsertValueGenerationType(
     Property mappingProperty, StandardProperty runtimeProperty) {
   if (runtimeProperty.isInsertGenerated()) {
     return ValueInclusion.FULL;
   } else if (mappingProperty.getValue() instanceof Component) {
     if (hasPartialInsertComponentGeneration((Component) mappingProperty.getValue())) {
       return ValueInclusion.PARTIAL;
     }
   }
   return ValueInclusion.NONE;
 }
Example #9
0
 private Property getConstrainedOneToOne(RootClass rc) {
   Iterator propertyClosureIterator = rc.getPropertyClosureIterator();
   while (propertyClosureIterator.hasNext()) {
     Property property = (Property) propertyClosureIterator.next();
     if (property.getValue() instanceof OneToOne) {
       OneToOne oto = (OneToOne) property.getValue();
       if (oto.isConstrained()) {
         return property;
       }
     }
   }
   return null;
 }
 private boolean hasPartialUpdateComponentGeneration(Component component) {
   Iterator subProperties = component.getPropertyIterator();
   while (subProperties.hasNext()) {
     Property prop = (Property) subProperties.next();
     if (isUpdateGenerated(prop)) {
       return true;
     } else if (prop.getValue() instanceof Component) {
       if (hasPartialUpdateComponentGeneration((Component) prop.getValue())) {
         return true;
       }
     }
   }
   return false;
 }
 private boolean hasPartialInsertComponentGeneration(Component component) {
   Iterator subProperties = component.getPropertyIterator();
   while (subProperties.hasNext()) {
     Property prop = (Property) subProperties.next();
     if (prop.getGeneration() == PropertyGeneration.ALWAYS
         || prop.getGeneration() == PropertyGeneration.INSERT) {
       return true;
     } else if (prop.getValue() instanceof Component) {
       if (hasPartialInsertComponentGeneration((Component) prop.getValue())) {
         return true;
       }
     }
   }
   return false;
 }
 @SuppressWarnings({"unchecked"})
 private String searchMappedBy(PersistentClass referencedClass, Table collectionTable) {
   Iterator<Property> properties = referencedClass.getPropertyIterator();
   while (properties.hasNext()) {
     Property property = properties.next();
     if (property.getValue() instanceof Collection) {
       // The equality is intentional. We want to find a collection property with the same
       // collection table.
       //noinspection ObjectEquality
       if (((Collection) property.getValue()).getCollectionTable() == collectionTable) {
         return property.getName();
       }
     }
   }
   return null;
 }
 public boolean isComponent(Property property) {
   Value value = property.getValue();
   if (value != null && value instanceof Component) {
     return true;
   } else {
     return false;
   }
 }
  public String generateBasicAnnotation(Property property) {
    StringBuffer annotations = new StringBuffer("    ");
    if (property.getValue() instanceof SimpleValue) {
      if (hasVersionProperty())
        if (property.equals(getVersionProperty())) buildVersionAnnotation(annotations);
      String typeName = ((SimpleValue) property.getValue()).getTypeName();
      if ("date".equals(typeName) || "java.sql.Date".equals(typeName)) {
        buildTemporalAnnotation(annotations, "DATE");
      } else if ("timestamp".equals(typeName) || "java.sql.Timestamp".equals(typeName)) {
        buildTemporalAnnotation(annotations, "TIMESTAMP");
      } else if ("time".equals(typeName) || "java.sql.Time".equals(typeName)) {
        buildTemporalAnnotation(annotations, "TIME");
      } // TODO: calendar etc. ?
    }

    return annotations.toString();
  }
 @SuppressWarnings("unchecked")
 private void createPropertiesGroupMapping(Property property) {
   final Component component = (Component) property.getValue();
   final Iterator<Property> componentProperties = component.getPropertyIterator();
   while (componentProperties.hasNext()) {
     final Property componentProperty = componentProperties.next();
     propertiesGroupMapping.put(componentProperty.getName(), component.getNodeName());
   }
 }
 private static void collectComponents(
     Map<String, Component> components, Iterator<Property> iter) {
   while (iter.hasNext()) {
     Property property = iter.next();
     if (!"embedded".equals(property.getPropertyAccessorName())
         && // HBX-267, embedded property for <properties> should not be generated as component.
         property.getValue() instanceof Component) {
       Component comp = (Component) property.getValue();
       addComponent(components, comp);
     } else if (property.getValue() instanceof Collection) {
       // compisite-element in collection
       Collection collection = (Collection) property.getValue();
       if (collection.getElement() instanceof Component) {
         Component comp = (Component) collection.getElement();
         addComponent(components, comp);
       }
     }
   }
 }
Example #17
0
  private Property bindMeta(Property property, TableIdentifier identifier) {
    Iterator columnIterator = property.getValue().getColumnIterator();
    while (columnIterator.hasNext()) {
      Column col = (Column) columnIterator.next();

      Map map = revengStrategy.columnToMetaAttributes(identifier, col.getName());
      if (map != null) { // TODO: merge from each column ?
        property.setMetaAttributes(map);
      }
    }

    return property;
  }
  @SuppressWarnings({"unchecked"})
  private String searchMappedBy(PersistentClass referencedClass, Collection collectionValue) {
    Iterator<Property> assocClassProps = referencedClass.getPropertyIterator();
    while (assocClassProps.hasNext()) {
      Property property = assocClassProps.next();

      if (Tools.iteratorsContentEqual(
          property.getValue().getColumnIterator(), collectionValue.getKey().getColumnIterator())) {
        return property.getName();
      }
    }
    return null;
  }
  private static GenerationStrategyPair buildGenerationStrategyPair(
      final SessionFactoryImplementor sessionFactory, final Property mappingProperty) {
    final ValueGeneration valueGeneration = mappingProperty.getValueGenerationStrategy();
    if (valueGeneration != null
        && valueGeneration.getGenerationTiming() != GenerationTiming.NEVER) {
      // the property is generated in full. build the generation strategy pair.
      if (valueGeneration.getValueGenerator() != null) {
        // in-memory generation
        return new GenerationStrategyPair(
            FullInMemoryValueGenerationStrategy.create(valueGeneration));
      } else {
        // in-db generation
        return new GenerationStrategyPair(create(sessionFactory, mappingProperty, valueGeneration));
      }
    } else if (mappingProperty.getValue() instanceof Component) {
      final CompositeGenerationStrategyPairBuilder builder =
          new CompositeGenerationStrategyPairBuilder(mappingProperty);
      interpretPartialCompositeValueGeneration(
          sessionFactory, (Component) mappingProperty.getValue(), builder);
      return builder.buildPair();
    }

    return NO_GEN_PAIR;
  }
 private void handleProperty(EntityType entityType, Class<?> cl, org.hibernate.mapping.Property p)
     throws NoSuchMethodException, ClassNotFoundException {
   Type propertyType = getType(cl, p.getName());
   if (p.isComposite()) {
     Class<?> embeddedClass = Class.forName(propertyType.getFullName());
     EntityType embeddedType = createEmbeddableType(embeddedClass);
     Iterator<?> properties = ((Component) p.getValue()).getPropertyIterator();
     while (properties.hasNext()) {
       handleProperty(
           embeddedType, embeddedClass, (org.hibernate.mapping.Property) properties.next());
     }
     propertyType = embeddedType;
   } else if (propertyType.getCategory() == TypeCategory.ENTITY) {
     propertyType = createEntityType(Class.forName(propertyType.getFullName()));
   }
   AnnotatedElement annotated = getAnnotatedElement(cl, p.getName());
   Property property = createProperty(entityType, p.getName(), propertyType, annotated);
   entityType.addProperty(property);
 }
Example #21
0
 @SuppressWarnings("unchecked")
 private void addSubElement(Property property, ValidatableElement element) {
   if (property != null && property.isComposite() && !property.isBackRef()) {
     Component component = (Component) property.getValue();
     if (component.isEmbedded()) return;
     PropertyAccessor accessor =
         PropertyAccessorFactory.getPropertyAccessor(property, EntityMode.POJO);
     Getter getter = accessor.getGetter(element.clazz, property.getName());
     ClassValidator validator = new ClassValidator(getter.getReturnType());
     ValidatableElement subElement =
         new ValidatableElement(getter.getReturnType(), validator, getter);
     Iterator properties = component.getPropertyIterator();
     while (properties.hasNext()) {
       addSubElement((Property) properties.next(), subElement);
     }
     if (subElement.getSubElements().size() != 0 || subElement.validator.hasValidationRules()) {
       element.addSubElement(subElement);
     }
   }
 }
  public String generateAnnColumnAnnotation(Property property) {
    StringBuffer annotations = new StringBuffer("    ");
    boolean insertable = property.isInsertable();
    boolean updatable = property.isUpdateable();
    if (property.isComposite()) {
      annotations.append("@" + importType("javax.persistence.AttributeOverrides") + "( {");
      Component component = (Component) property.getValue();
      Iterator<?> subElements = component.getPropertyIterator();
      buildRecursiveAttributeOverride(subElements, null, property, annotations);
      annotations.setLength(annotations.length() - 2);
      annotations.append(" } )");
    } else {
      if (property.getColumnSpan() == 1) {
        Selectable selectable = (Selectable) property.getColumnIterator().next();
        buildColumnAnnotation(selectable, annotations, insertable, updatable);
      } else {
        Iterator<?> columns = property.getColumnIterator();
        annotations
            .append("@")
            .append(importType("org.hibernate.annotations.Columns"))
            .append("( { ");
        while (columns.hasNext()) {
          Selectable selectable = (Selectable) columns.next();

          if (selectable.isFormula()) {
            // TODO formula in multicolumns not supported by annotations
            // annotations.append("/* TODO formula in multicolumns not supported by annotations
            // */");
          } else {
            annotations.append("\n        ");
            buildColumnAnnotation(selectable, annotations, insertable, updatable);
            annotations.append(", ");
          }
        }
        annotations.setLength(annotations.length() - 2);
        annotations.append(" } )");
      }
    }
    return annotations.toString();
  }
  @SuppressWarnings({"unchecked"})
  private boolean addIdProperties(
      Element parent,
      Iterator<Property> properties,
      SimpleMapperBuilder mapper,
      boolean key,
      boolean audited) {
    while (properties.hasNext()) {
      Property property = properties.next();
      Type propertyType = property.getType();
      if (!"_identifierMapper".equals(property.getName())) {
        // Last but one parameter: ids are always insertable
        boolean added =
            mainGenerator
                .getBasicMetadataGenerator()
                .addBasic(
                    parent,
                    getIdPersistentPropertyAuditingData(property),
                    property.getValue(),
                    mapper,
                    true,
                    key);

        if (!added) {
          // If the entity is audited, and a non-supported id component is used, throwing an
          // exception.
          // If the entity is not audited, then we simply don't support this entity, even in
          // target relation mode not audited.
          if (audited) {
            throw new MappingException("Type not supported: " + propertyType.getClass().getName());
          } else {
            return false;
          }
        }
      }
    }

    return true;
  }
  /**
   * calculated the max length of an attribute of type String
   *
   * @param c Cluster that holds the attribute
   * @param attributeName name of the attribute
   * @return max allowed length of the attribute
   */
  public int getLenthOfStringAttribute(ICluster c, String attributeName) {

    Assert.notNull(c, "c may not be null");
    Assert.notNull(attributeName, "attributeName may not be null");

    PersistentClass pc = cfg.getClassMapping(c.getDaoClass().getName());

    if (pc == null)
      throw new ConfigurationException(
          "Persistent Dao Class from Cluster "
              + c.getClass().getName()
              + " is not Hibernate configured");

    Property p = pc.getProperty(attributeName);

    if (p == null)
      throw new ConfigurationException(
          "Property " + attributeName + " in cluster " + c.getClass().getName() + " not found");

    Iterator<Column> i = (Iterator<Column>) p.getValue().getColumnIterator();
    Column column = i.next();
    return column.getLength();
  }
  /**
   * 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;
  }
 private void buildRecursiveAttributeOverride(
     Iterator<?> subElements, String path, Property property, StringBuffer annotations) {
   while (subElements.hasNext()) {
     Property subProperty = (Property) subElements.next();
     if (subProperty.isComposite()) {
       if (path != null) {
         path = path + ".";
       } else {
         path = "";
       }
       path = path + subProperty.getName();
       Component component = (Component) subProperty.getValue();
       buildRecursiveAttributeOverride(
           component.getPropertyIterator(), path, subProperty, annotations);
     } else {
       Iterator<?> columns = subProperty.getColumnIterator();
       Selectable selectable = (Selectable) columns.next();
       if (selectable.isFormula()) {
         // TODO formula in multicolumns not supported by annotations
       } else {
         annotations
             .append("\n        ")
             .append("@")
             .append(importType("javax.persistence.AttributeOverride"))
             .append("(name=\"");
         if (path != null) {
           annotations.append(path).append(".");
         }
         annotations.append(subProperty.getName()).append("\"").append(", column=");
         buildColumnAnnotation(
             selectable, annotations, subProperty.isInsertable(), subProperty.isUpdateable());
         annotations.append(" ), ");
       }
     }
   }
 }
  @SuppressWarnings({"unchecked"})
  public void wrapUp() {
    LOG.trace("Wrapping up metadata context...");

    // we need to process types from superclasses to subclasses
    for (Object mapping : orderedMappings) {
      if (PersistentClass.class.isAssignableFrom(mapping.getClass())) {
        @SuppressWarnings("unchecked")
        final PersistentClass safeMapping = (PersistentClass) mapping;
        LOG.trace("Starting entity [" + safeMapping.getEntityName() + "]");
        try {
          final EntityTypeImpl<?> jpa2Mapping = entityTypesByPersistentClass.get(safeMapping);
          applyIdMetadata(safeMapping, jpa2Mapping);
          applyVersionAttribute(safeMapping, jpa2Mapping);
          Iterator<Property> properties = safeMapping.getDeclaredPropertyIterator();
          while (properties.hasNext()) {
            final Property property = properties.next();
            if (property.getValue() == safeMapping.getIdentifierMapper()) {
              // property represents special handling for id-class mappings but we have already
              // accounted for the embedded property mappings in #applyIdMetadata &&
              // #buildIdClassAttributes
              continue;
            }
            if (safeMapping.isVersioned() && property == safeMapping.getVersion()) {
              // skip the version property, it was already handled previously.
              continue;
            }
            final Attribute attribute = attributeFactory.buildAttribute(jpa2Mapping, property);
            if (attribute != null) {
              jpa2Mapping.getBuilder().addAttribute(attribute);
            }
          }
          jpa2Mapping.lock();
          populateStaticMetamodel(jpa2Mapping);
        } finally {
          LOG.trace("Completed entity [" + safeMapping.getEntityName() + "]");
        }
      } else if (MappedSuperclass.class.isAssignableFrom(mapping.getClass())) {
        @SuppressWarnings("unchecked")
        final MappedSuperclass safeMapping = (MappedSuperclass) mapping;
        LOG.trace("Starting mapped superclass [" + safeMapping.getMappedClass().getName() + "]");
        try {
          final MappedSuperclassTypeImpl<?> jpa2Mapping =
              mappedSuperclassByMappedSuperclassMapping.get(safeMapping);
          applyIdMetadata(safeMapping, jpa2Mapping);
          applyVersionAttribute(safeMapping, jpa2Mapping);
          Iterator<Property> properties = safeMapping.getDeclaredPropertyIterator();
          while (properties.hasNext()) {
            final Property property = properties.next();
            if (safeMapping.isVersioned() && property == safeMapping.getVersion()) {
              // skip the version property, it was already handled previously.
              continue;
            }
            final Attribute attribute = attributeFactory.buildAttribute(jpa2Mapping, property);
            if (attribute != null) {
              jpa2Mapping.getBuilder().addAttribute(attribute);
            }
          }
          jpa2Mapping.lock();
          populateStaticMetamodel(jpa2Mapping);
        } finally {
          LOG.trace("Completed mapped superclass [" + safeMapping.getMappedClass().getName() + "]");
        }
      } else {
        throw new AssertionFailure("Unexpected mapping type: " + mapping.getClass());
      }
    }

    for (EmbeddableTypeImpl embeddable : embeddables.values()) {
      populateStaticMetamodel(embeddable);
    }
  }
  public String getFieldInitialization(Property p, boolean useGenerics) {
    if (hasMetaAttribute(p, "default-value")) {
      return MetaAttributeHelper.getMetaAsString(p.getMetaAttribute("default-value"));
    }
    if (c2j.getJavaTypeName(p, false) == null) {
      throw new IllegalArgumentException();
    } else if (p.getValue() instanceof Collection) {
      Collection col = (Collection) p.getValue();

      DefaultInitializor initialization =
          (DefaultInitializor)
              col.accept(
                  new DefaultValueVisitor(true) {

                    public Object accept(Bag o) {
                      return new DefaultInitializor("java.util.ArrayList", true);
                    }

                    public Object accept(org.hibernate.mapping.List o) {
                      return new DefaultInitializor("java.util.ArrayList", true);
                    }

                    public Object accept(org.hibernate.mapping.Map o) {
                      if (o.isSorted()) {
                        return new DefaultInitializor("java.util.TreeMap", false);
                      } else {
                        return new DefaultInitializor("java.util.HashMap", true);
                      }
                    }

                    public Object accept(IdentifierBag o) {
                      return new DefaultInitializor("java.util.ArrayList", true);
                    }

                    public Object accept(Set o) {
                      if (o.isSorted()) {
                        return new DefaultInitializor("java.util.TreeSet", false);
                      } else {
                        return new DefaultInitializor("java.util.HashSet", true);
                      }
                    }

                    public Object accept(PrimitiveArray o) {
                      return null; // TODO: default init for arrays ?
                    }

                    public Object accept(Array o) {
                      return null; // TODO: default init for arrays ?
                    }
                  });

      if (initialization != null) {
        String comparator = null;
        String decl = null;

        if (col.isSorted()) {
          comparator = col.getComparatorClassName();
        }

        if (useGenerics) {
          decl =
              c2j.getGenericCollectionDeclaration((Collection) p.getValue(), true, importContext);
        }
        return initialization.getDefaultValue(comparator, decl, this);
      } else {
        return null;
      }
    } else {
      return null;
    }
  }
    public GenerationStrategyPair buildPair() {
      if (hadInMemoryGeneration && hadInDatabaseGeneration) {
        throw new ValueGenerationStrategyException(
            "Composite attribute ["
                + mappingProperty.getName()
                + "] contained both in-memory"
                + " and in-database value generation");
      } else if (hadInMemoryGeneration) {
        throw new NotYetImplementedException(
            "Still need to wire in composite in-memory value generation");

      } else if (hadInDatabaseGeneration) {
        final Component composite = (Component) mappingProperty.getValue();

        // we need the numbers to match up so we can properly handle 'referenced sql column values'
        if (inDatabaseStrategies.size() != composite.getPropertySpan()) {
          throw new ValueGenerationStrategyException(
              "Internal error : mismatch between number of collected in-db generation strategies"
                  + " and number of attributes for composite attribute : "
                  + mappingProperty.getName());
        }

        // the base-line values for the aggregated InDatabaseValueGenerationStrategy we will build
        // here.
        GenerationTiming timing = GenerationTiming.INSERT;
        boolean referenceColumns = false;
        String[] columnValues = new String[composite.getColumnSpan()];

        // start building the aggregate values
        int propertyIndex = -1;
        int columnIndex = 0;
        Iterator subProperties = composite.getPropertyIterator();
        while (subProperties.hasNext()) {
          propertyIndex++;
          final Property subProperty = (Property) subProperties.next();
          final InDatabaseValueGenerationStrategy subStrategy =
              inDatabaseStrategies.get(propertyIndex);

          if (subStrategy.getGenerationTiming() == GenerationTiming.ALWAYS) {
            // override the base-line to the more often "ALWAYS"...
            timing = GenerationTiming.ALWAYS;
          }
          if (subStrategy.referenceColumnsInSql()) {
            // override base-line value
            referenceColumns = true;
          }
          if (subStrategy.getReferencedColumnValues() != null) {
            if (subStrategy.getReferencedColumnValues().length != subProperty.getColumnSpan()) {
              throw new ValueGenerationStrategyException(
                  "Internal error : mismatch between number of collected 'referenced column values'"
                      + " and number of columns for composite attribute : "
                      + mappingProperty.getName()
                      + '.'
                      + subProperty.getName());
            }
            System.arraycopy(
                subStrategy.getReferencedColumnValues(),
                0,
                columnValues,
                columnIndex,
                subProperty.getColumnSpan());
          }
        }

        // then use the aggregated values to build the InDatabaseValueGenerationStrategy
        return new GenerationStrategyPair(
            new InDatabaseValueGenerationStrategyImpl(timing, referenceColumns, columnValues));
      } else {
        return NO_GEN_PAIR;
      }
    }
  @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);
      }
    }
  }