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;
  }
  @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());
  }
  /**
   * 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);
  }
  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 static boolean isUpdateGenerated(Property property) {
   return property.getValueGenerationStrategy() != null
       && property.getValueGenerationStrategy().getGenerationTiming() == GenerationTiming.ALWAYS;
 }
 private boolean isInsertGenerated(Property property) {
   return property.getValueGenerationStrategy() != null
       && property.getValueGenerationStrategy().getGenerationTiming() != GenerationTiming.NEVER;
 }
  /**
   * Generate a non-identifier (and non-version) attribute based on the given mapped property from
   * the given entity
   *
   * @param property The mapped property.
   * @param lazyAvailable Is property lazy loading currently available.
   * @return The appropriate NonIdentifierProperty definition.
   */
  public static NonIdentifierAttribute buildEntityBasedAttribute(
      EntityPersister persister,
      SessionFactoryImplementor sessionFactory,
      int attributeNumber,
      Property property,
      boolean lazyAvailable) {
    final Type type = property.getValue().getType();

    final NonIdentifierAttributeNature nature = decode(type);

    // 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();

    switch (nature) {
      case BASIC:
        {
          return new EntityBasedBasicAttribute(
              persister,
              sessionFactory,
              attributeNumber,
              property.getName(),
              type,
              new BaselineAttributeInformation.Builder()
                  .setLazy(lazyAvailable && property.isLazy())
                  .setInsertable(property.isInsertable())
                  .setUpdateable(property.isUpdateable())
                  .setValueGenerationStrategy(property.getValueGenerationStrategy())
                  .setNullable(property.isOptional())
                  .setDirtyCheckable(alwaysDirtyCheck || property.isUpdateable())
                  .setVersionable(property.isOptimisticLocked())
                  .setCascadeStyle(property.getCascadeStyle())
                  .setFetchMode(property.getValue().getFetchMode())
                  .createInformation());
        }
      case COMPOSITE:
        {
          return new EntityBasedCompositionAttribute(
              persister,
              sessionFactory,
              attributeNumber,
              property.getName(),
              (CompositeType) type,
              new BaselineAttributeInformation.Builder()
                  .setLazy(lazyAvailable && property.isLazy())
                  .setInsertable(property.isInsertable())
                  .setUpdateable(property.isUpdateable())
                  .setValueGenerationStrategy(property.getValueGenerationStrategy())
                  .setNullable(property.isOptional())
                  .setDirtyCheckable(alwaysDirtyCheck || property.isUpdateable())
                  .setVersionable(property.isOptimisticLocked())
                  .setCascadeStyle(property.getCascadeStyle())
                  .setFetchMode(property.getValue().getFetchMode())
                  .createInformation());
        }
      case ENTITY:
      case ANY:
      case COLLECTION:
        {
          return new EntityBasedAssociationAttribute(
              persister,
              sessionFactory,
              attributeNumber,
              property.getName(),
              (AssociationType) type,
              new BaselineAttributeInformation.Builder()
                  .setLazy(lazyAvailable && property.isLazy())
                  .setInsertable(property.isInsertable())
                  .setUpdateable(property.isUpdateable())
                  .setValueGenerationStrategy(property.getValueGenerationStrategy())
                  .setNullable(property.isOptional())
                  .setDirtyCheckable(alwaysDirtyCheck || property.isUpdateable())
                  .setVersionable(property.isOptimisticLocked())
                  .setCascadeStyle(property.getCascadeStyle())
                  .setFetchMode(property.getValue().getFetchMode())
                  .createInformation());
        }
      default:
        {
          throw new HibernateException("Internal error");
        }
    }
  }