@Before
  public void setUp() throws Exception {
    serviceRegistry =
        new StandardServiceRegistryBuilder()
            .enableAutoClose()
            .applySetting(AvailableSettings.HBM2DDL_AUTO, "create-drop")
            .build();

    MetadataBuildingContext buildingContext =
        new MetadataBuildingContextTestingImpl(serviceRegistry);

    Properties properties = new Properties();
    properties.setProperty(SequenceGenerator.SEQUENCE, TEST_SEQUENCE);
    properties.setProperty(SequenceHiLoGenerator.MAX_LO, "3");
    properties.put(
        PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
        buildingContext.getObjectNameNormalizer());

    generator = new SequenceHiLoGenerator();
    generator.configure(
        StandardBasicTypes.LONG, properties, serviceRegistry.getService(JdbcEnvironment.class));

    Metadata metadata = new MetadataSources(serviceRegistry).buildMetadata();
    generator.registerExportables(metadata.getDatabase());

    sessionFactory = (SessionFactoryImplementor) metadata.buildSessionFactory();
  }
  public static int checkReferencedColumnsType(
      Ejb3JoinColumn[] columns, PersistentClass referencedEntity, MetadataBuildingContext context) {
    // convenient container to find whether a column is an id one or not
    Set<Column> idColumns = new HashSet<Column>();
    Iterator idColumnsIt = referencedEntity.getKey().getColumnIterator();
    while (idColumnsIt.hasNext()) {
      idColumns.add((Column) idColumnsIt.next());
    }

    boolean isFkReferencedColumnName = false;
    boolean noReferencedColumn = true;
    // build the list of potential tables
    if (columns.length == 0) return NO_REFERENCE; // shortcut
    Object columnOwner =
        BinderHelper.findColumnOwner(referencedEntity, columns[0].getReferencedColumn(), context);
    if (columnOwner == null) {
      try {
        throw new MappingException(
            "Unable to find column with logical name: "
                + columns[0].getReferencedColumn()
                + " in "
                + referencedEntity.getTable()
                + " and its related "
                + "supertables and secondary tables");
      } catch (MappingException e) {
        throw new RecoverableException(e.getMessage(), e);
      }
    }
    Table matchingTable =
        columnOwner instanceof PersistentClass
            ? ((PersistentClass) columnOwner).getTable()
            : ((Join) columnOwner).getTable();
    // check each referenced column
    for (Ejb3JoinColumn ejb3Column : columns) {
      String logicalReferencedColumnName = ejb3Column.getReferencedColumn();
      if (StringHelper.isNotEmpty(logicalReferencedColumnName)) {
        String referencedColumnName;
        try {
          referencedColumnName =
              context
                  .getMetadataCollector()
                  .getPhysicalColumnName(matchingTable, logicalReferencedColumnName);
        } catch (MappingException me) {
          // rewrite the exception
          throw new MappingException(
              "Unable to find column with logical name: "
                  + logicalReferencedColumnName
                  + " in "
                  + matchingTable.getName());
        }
        noReferencedColumn = false;
        Column refCol = new Column(referencedColumnName);
        boolean contains = idColumns.contains(refCol);
        if (!contains) {
          isFkReferencedColumnName = true;
          break; // we know the state
        }
      }
    }
    if (isFkReferencedColumnName) {
      return NON_PK_REFERENCE;
    } else if (noReferencedColumn) {
      return NO_REFERENCE;
    } else if (idColumns.size() != columns.length) {
      // reference use PK but is a subset or a superset
      return NON_PK_REFERENCE;
    } else {
      return PK_REFERENCE;
    }
  }
  /** Build JoinColumn for a JOINED hierarchy */
  public static Ejb3JoinColumn buildJoinColumn(
      PrimaryKeyJoinColumn pkJoinAnn,
      JoinColumn joinAnn,
      Value identifier,
      Map<String, Join> joins,
      PropertyHolder propertyHolder,
      MetadataBuildingContext context) {

    final ObjectNameNormalizer normalizer = context.getObjectNameNormalizer();

    Column col = (Column) identifier.getColumnIterator().next();
    String defaultName =
        context
            .getMetadataCollector()
            .getLogicalColumnName(identifier.getTable(), col.getQuotedName());

    if (pkJoinAnn != null || joinAnn != null) {
      String colName;
      String columnDefinition;
      String referencedColumnName;
      if (pkJoinAnn != null) {
        colName = pkJoinAnn.name();
        columnDefinition = pkJoinAnn.columnDefinition();
        referencedColumnName = pkJoinAnn.referencedColumnName();
      } else {
        colName = joinAnn.name();
        columnDefinition = joinAnn.columnDefinition();
        referencedColumnName = joinAnn.referencedColumnName();
      }

      final String sqlType;
      if (columnDefinition.equals("")) {
        sqlType = null;
      } else {
        sqlType = normalizer.toDatabaseIdentifierText(columnDefinition);
      }

      final String name;
      if ("".equals(colName)) {
        name = normalizer.normalizeIdentifierQuotingAsString(defaultName);
      } else {
        name = context.getObjectNameNormalizer().normalizeIdentifierQuotingAsString(colName);
      }
      return new Ejb3JoinColumn(
          sqlType,
          name,
          false,
          false,
          true,
          true,
          referencedColumnName,
          null,
          joins,
          propertyHolder,
          null,
          null,
          false,
          context);
    } else {
      defaultName =
          context.getObjectNameNormalizer().normalizeIdentifierQuotingAsString(defaultName);
      return new Ejb3JoinColumn(
          null,
          defaultName,
          false,
          false,
          true,
          true,
          null,
          null,
          joins,
          propertyHolder,
          null,
          null,
          true,
          context);
    }
  }