private void readColumn(Column columnAnn, DeployBeanProperty prop) {

    if (!isEmpty(columnAnn.name())) {
      String dbColumn = databasePlatform.convertQuotedIdentifiers(columnAnn.name());
      prop.setDbColumn(dbColumn);
    }

    prop.setDbInsertable(columnAnn.insertable());
    prop.setDbUpdateable(columnAnn.updatable());
    prop.setNullable(columnAnn.nullable());
    prop.setUnique(columnAnn.unique());
    if (columnAnn.precision() > 0) {
      prop.setDbLength(columnAnn.precision());
    } else if (columnAnn.length() != 255) {
      // set default 255 on DbTypeMap
      prop.setDbLength(columnAnn.length());
    }
    prop.setDbScale(columnAnn.scale());
    prop.setDbColumnDefn(columnAnn.columnDefinition());

    String baseTable = descriptor.getBaseTable();
    String tableName = columnAnn.table();
    if (tableName.equals("") || tableName.equalsIgnoreCase(baseTable)) {
      // its a base table property...
    } else {
      // its on a secondary table...
      prop.setSecondaryTable(tableName);
      // DeployTableJoin tableJoin = info.getTableJoin(tableName);
      // tableJoin.addProperty(prop);
    }
  }
  /** Read the Id marker annotations on EmbeddedId properties. */
  private void readAssocOne(DeployBeanProperty prop) {

    Id id = get(prop, Id.class);
    if (id != null) {
      prop.setId(true);
      prop.setNullable(false);
    }

    EmbeddedId embeddedId = get(prop, EmbeddedId.class);
    if (embeddedId != null) {
      prop.setId(true);
      prop.setNullable(false);
      prop.setEmbedded(true);
    }

    if (prop instanceof DeployBeanPropertyAssocOne<?>) {
      if (prop.isId() && !prop.isEmbedded()) {
        prop.setEmbedded(true);
      }
      readEmbeddedAttributeOverrides((DeployBeanPropertyAssocOne<?>) prop);
    }
  }
  private void readId(Id id, DeployBeanProperty prop) {

    prop.setId(true);
    prop.setNullable(false);

    if (prop.getPropertyType().equals(UUID.class)) {
      // An Id of type UUID
      if (descriptor.getIdGeneratorName() == null) {
        // Without a generator explicitly specified
        // so will use the default one AUTO_UUID
        descriptor.setIdGeneratorName(UuidIdGenerator.AUTO_UUID);
        descriptor.setIdType(IdType.GENERATOR);
      }
    }
  }
  private void readField(DeployBeanProperty prop) {

    // all Enums will have a ScalarType assigned...
    boolean isEnum = prop.getPropertyType().isEnum();
    Enumerated enumerated = get(prop, Enumerated.class);
    if (isEnum || enumerated != null) {
      util.setEnumScalarType(enumerated, prop);
    }

    // its persistent and assumed to be on the base table
    // rather than on a secondary table
    prop.setDbRead(true);
    prop.setDbInsertable(true);
    prop.setDbUpdateable(true);

    Column column = get(prop, Column.class);
    if (column != null) {
      readColumn(column, prop);
    }
    Expose expose = get(prop, Expose.class);
    if (expose != null) {
      prop.setExposeSerialize(expose.serialize());
      prop.setExposeDeserialize(expose.deserialize());
    }

    if (prop.getDbColumn() == null) {
      // No @Column annotation or @Column.name() not set
      // Use the NamingConvention to set the DB column name
      String dbColumn = namingConvention.getColumnFromProperty(beanType, prop.getName());
      prop.setDbColumn(dbColumn);
    }

    GeneratedValue gen = get(prop, GeneratedValue.class);
    if (gen != null) {
      readGenValue(gen, prop);
    }

    Id id = (Id) get(prop, Id.class);
    if (id != null) {
      readId(id, prop);
    }

    // determine the JDBC type using Lob/Temporal
    // otherwise based on the property Class
    Lob lob = get(prop, Lob.class);
    Temporal temporal = get(prop, Temporal.class);
    if (temporal != null) {
      readTemporal(temporal, prop);

    } else if (lob != null) {
      util.setLobType(prop);
    }

    Formula formula = get(prop, Formula.class);
    if (formula != null) {
      prop.setSqlFormula(formula.select(), formula.join());
    }

    Version version = get(prop, Version.class);
    if (version != null) {
      // explicitly specify a version column
      prop.setVersionColumn(true);
      generatedPropFactory.setVersion(prop);
    }

    Basic basic = get(prop, Basic.class);
    if (basic != null) {
      prop.setFetchType(basic.fetch());
      if (!basic.optional()) {
        prop.setNullable(false);
      }
    } else if (prop.isLob()) {
      // use the default Lob fetchType
      prop.setFetchType(defaultLobFetchType);
    }

    CreatedTimestamp ct = get(prop, CreatedTimestamp.class);
    if (ct != null) {
      generatedPropFactory.setInsertTimestamp(prop);
    }

    UpdatedTimestamp ut = get(prop, UpdatedTimestamp.class);
    if (ut != null) {
      generatedPropFactory.setUpdateTimestamp(prop);
    }

    if (validationAnnotations) {
      NotNull notNull = get(prop, NotNull.class);
      if (notNull != null && isNotNullOnAllValidationGroups(notNull.groups())) {
        // Not null on all validation groups so enable
        // DDL generation of Not Null Constraint
        prop.setNullable(false);
      }

      Size size = get(prop, Size.class);
      if (size != null) {
        if (size.max() < Integer.MAX_VALUE) {
          // explicitly specify a version column
          prop.setDbLength(size.max());
        }
      }
    }

    EmbeddedColumns columns = get(prop, EmbeddedColumns.class);
    if (columns != null) {
      if (prop instanceof DeployBeanPropertyCompound) {
        DeployBeanPropertyCompound p = (DeployBeanPropertyCompound) prop;

        // convert into a Map
        String propColumns = columns.columns();
        Map<String, String> propMap = StringHelper.delimitedToMap(propColumns, ",", "=");

        p.getDeployEmbedded().putAll(propMap);

        CtCompoundType<?> compoundType = p.getCompoundType();
        if (compoundType == null) {
          throw new RuntimeException("No registered CtCompoundType for " + p.getPropertyType());
        }

      } else {
        throw new RuntimeException(
            "Can't use EmbeddedColumns on ScalarType " + prop.getFullBeanName());
      }
    }

    // Want to process last so we can use with @Formula
    Transient t = get(prop, Transient.class);
    if (t != null) {
      // it is not a persistent property.
      prop.setDbRead(false);
      prop.setDbInsertable(false);
      prop.setDbUpdateable(false);
      prop.setTransient(true);
    }

    if (!prop.isTransient()) {

      EncryptDeploy encryptDeploy =
          util.getEncryptDeploy(info.getDescriptor().getBaseTableFull(), prop.getDbColumn());
      if (encryptDeploy == null || encryptDeploy.getMode().equals(Mode.MODE_ANNOTATION)) {
        Encrypted encrypted = get(prop, Encrypted.class);
        if (encrypted != null) {
          setEncryption(prop, encrypted.dbEncryption(), encrypted.dbLength());
        }
      } else if (Mode.MODE_ENCRYPT.equals(encryptDeploy.getMode())) {
        setEncryption(prop, encryptDeploy.isDbEncrypt(), encryptDeploy.getDbLength());
      }
    }

    Index index = get(prop, Index.class);
    if (index != null) {
      if (hasRelationshipItem(prop)) {
        throw new RuntimeException("Can't use Index on foreign key relationships.");
      }
      prop.setIndexed(true);
      prop.setIndexName(index.value());
    }
  }