/**
   * Prepares the save call using a newly generated id.
   *
   * @param entity The entity to be saved
   * @param entityName The entity-name for the entity to be saved
   * @param anything Generally cascade-specific information.
   * @param source The session which is the source of this save event.
   * @param requiresImmediateIdAccess does the event context require access to the identifier
   *     immediately after execution of this method (if not, post-insert style id generators may be
   *     postponed if we are outside a transaction).
   * @return The id used to save the entity; may be null depending on the type of id generator used
   *     and the requiresImmediateIdAccess value
   */
  protected Serializable saveWithGeneratedId(
      Object entity,
      String entityName,
      Object anything,
      EventSource source,
      boolean requiresImmediateIdAccess) {
    EntityPersister persister = source.getEntityPersister(entityName, entity);
    Serializable generatedId = persister.getIdentifierGenerator().generate(source, entity);
    if (generatedId == null) {
      throw new IdentifierGenerationException("null id generated for:" + entity.getClass());
    } else if (generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR) {
      return source.getIdentifier(entity);
    } else if (generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR) {
      return performSave(
          entity, null, persister, true, anything, source, requiresImmediateIdAccess);
    } else {
      // TODO: define toString()s for generators
      if (LOG.isDebugEnabled()) {
        LOG.debugf(
            "Generated identifier: %s, using strategy: %s",
            persister.getIdentifierType().toLoggableString(generatedId, source.getFactory()),
            persister.getIdentifierGenerator().getClass().getName());
      }

      return performSave(entity, generatedId, persister, false, anything, source, true);
    }
  }
  /**
   * Returns all the persistent id generators which potentially require the creation of an object in
   * the schema.
   */
  private Iterable<PersistentNoSqlIdentifierGenerator> getPersistentGenerators() {
    Map<String, EntityPersister> entityPersisters = factory.getEntityPersisters();

    Set<PersistentNoSqlIdentifierGenerator> persistentGenerators =
        new HashSet<PersistentNoSqlIdentifierGenerator>(entityPersisters.size());
    for (EntityPersister persister : entityPersisters.values()) {
      if (persister.getIdentifierGenerator() instanceof PersistentNoSqlIdentifierGenerator) {
        persistentGenerators.add(
            (PersistentNoSqlIdentifierGenerator) persister.getIdentifierGenerator());
      }
    }

    return persistentGenerators;
  }
  public void testNormalBoundary() {
    EntityPersister persister = sfi().getEntityPersister(Entity.class.getName());
    assertClassAssignability(TableGenerator.class, persister.getIdentifierGenerator().getClass());
    TableGenerator generator = (TableGenerator) persister.getIdentifierGenerator();
    assertClassAssignability(
        OptimizerFactory.HiLoOptimizer.class, generator.getOptimizer().getClass());
    OptimizerFactory.HiLoOptimizer optimizer =
        (OptimizerFactory.HiLoOptimizer) generator.getOptimizer();

    int increment = optimizer.getIncrementSize();
    Entity[] entities = new Entity[increment + 1];
    Session s = openSession();
    s.beginTransaction();
    for (int i = 0; i < increment; i++) {
      entities[i] = new Entity("" + (i + 1));
      s.save(entities[i]);
      assertEquals(1, generator.getTableAccessCount()); // initialization
      assertEquals(
          1, ((BasicHolder) optimizer.getLastSourceValue()).getActualLongValue()); // initialization
      assertEquals(i + 1, ((BasicHolder) optimizer.getLastValue()).getActualLongValue());
      assertEquals(increment + 1, ((BasicHolder) optimizer.getHiValue()).getActualLongValue());
    }
    // now force a "clock over"
    entities[increment] = new Entity("" + increment);
    s.save(entities[increment]);
    assertEquals(2, generator.getTableAccessCount()); // initialization
    assertEquals(
        2, ((BasicHolder) optimizer.getLastSourceValue()).getActualLongValue()); // initialization
    assertEquals(increment + 1, ((BasicHolder) optimizer.getLastValue()).getActualLongValue());
    assertEquals((increment * 2) + 1, ((BasicHolder) optimizer.getHiValue()).getActualLongValue());

    s.getTransaction().commit();

    s.beginTransaction();
    for (int i = 0; i < entities.length; i++) {
      assertEquals(i + 1, entities[i].getId().intValue());
      s.delete(entities[i]);
    }
    s.getTransaction().commit();
    s.close();
  }
 @Test
 @FailureExpectedWithNewMetamodel
 public void testHibernateSequenceSchema() {
   EntityPersister persister =
       sessionFactory().getEntityPersister(HibernateSequenceEntity.class.getName());
   IdentifierGenerator generator = persister.getIdentifierGenerator();
   Assert.assertTrue(SequenceStyleGenerator.class.isInstance(generator));
   SequenceStyleGenerator seqGenerator = (SequenceStyleGenerator) generator;
   Assert.assertEquals(
       Table.qualify(null, SCHEMA_NAME, SequenceStyleGenerator.DEF_SEQUENCE_NAME),
       seqGenerator.getDatabaseStructure().getName());
 }
 protected boolean supportsBulkInsertIdGeneration(Class entityClass) {
   EntityPersister persister = sessionFactory().getEntityPersister(entityClass.getName());
   IdentifierGenerator generator = persister.getIdentifierGenerator();
   return HqlSqlWalker.supportsIdGenWithBulkInsertion(generator);
 }