private void prepareTestData(Session session) throws HibernateException {
    try {
      IdentifierGenerator stockIdGen =
          ((SessionFactoryImplementor) session.getSessionFactory())
              .getIdentifierGenerator(Stock.class.getName());
      IdentifierGenerator valIdGen =
          ((SessionFactoryImplementor) session.getSessionFactory())
              .getIdentifierGenerator(Valuation.class.getName());

      stockId = (Long) stockIdGen.generate((SessionImpl) session, null);
      valId = (Long) valIdGen.generate((SessionImpl) session, null);

      Connection conn = session.connection();
      PreparedStatement ps = conn.prepareStatement("INSERT INTO STOCK VALUES (?,?,?)");
      ps.setLong(1, stockId.longValue());
      ps.setString(2, "JBOSS");
      ps.setNull(3, Types.BIGINT);
      ps.executeUpdate();
      ps.close();

      ps = conn.prepareStatement("INSERT INTO STOCK_VAL VALUES (?,?,?,?)");
      ps.setLong(1, valId.longValue());
      ps.setLong(2, stockId.longValue());
      ps.setDate(3, new Date(new java.util.Date().getTime()));
      ps.setDouble(4, 200.0);
      ps.executeUpdate();
      ps.close();

      ps = conn.prepareStatement("UPDATE STOCK SET CURR_VAL_ID = ? WHERE STOCK_ID = ?");
      ps.setLong(1, valId.longValue());
      ps.setLong(2, stockId.longValue());
      ps.executeUpdate();
      ps.close();
    } catch (SQLException e) {
      System.err.println("Error : " + e);
      e.printStackTrace();
      throw new HibernateException("Unable to generate test data", e);
    }
  }
  public EntityManagerFactoryImpl(
      String persistenceUnitName,
      SessionFactoryImplementor sessionFactory,
      SettingsImpl settings,
      Map<?, ?> configurationValues,
      Configuration cfg) {
    this.sessionFactory = (SessionFactoryImpl) sessionFactory;
    this.transactionType = settings.getTransactionType();
    this.discardOnClose = settings.isReleaseResourcesOnCloseEnabled();
    this.sessionInterceptorClass = settings.getSessionInterceptorClass();

    final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting =
        determineJpaMetaModelPopulationSetting(cfg);
    if (JpaMetaModelPopulationSetting.DISABLED == jpaMetaModelPopulationSetting) {
      this.metamodel = null;
    } else {
      this.metamodel =
          MetamodelImpl.buildMetamodel(
              cfg.getClassMappings(),
              cfg.getMappedSuperclassMappingsCopy(),
              sessionFactory,
              JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED == jpaMetaModelPopulationSetting);
    }
    this.criteriaBuilder = new CriteriaBuilderImpl(this);
    this.util = new HibernatePersistenceUnitUtil(this);

    HashMap<String, Object> props = new HashMap<String, Object>();
    addAll(props, sessionFactory.getProperties());
    addAll(props, cfg.getProperties());
    addAll(props, configurationValues);
    maskOutSensitiveInformation(props);
    this.properties = Collections.unmodifiableMap(props);
    String entityManagerFactoryName =
        (String) this.properties.get(AvailableSettings.ENTITY_MANAGER_FACTORY_NAME);
    if (entityManagerFactoryName == null) {
      entityManagerFactoryName = persistenceUnitName;
    }
    if (entityManagerFactoryName == null) {
      entityManagerFactoryName = (String) UUID_GENERATOR.generate(null, null);
    }
    this.entityManagerFactoryName = entityManagerFactoryName;

    applyNamedEntityGraphs(cfg.getNamedEntityGraphs());

    EntityManagerFactoryRegistry.INSTANCE.addEntityManagerFactory(entityManagerFactoryName, this);
  }
  protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
    InsertStatement insertStatement = (InsertStatement) insert;
    insertStatement.validate();

    SelectClause selectClause = insertStatement.getSelectClause();
    Queryable persister = insertStatement.getIntoClause().getQueryable();

    if (!insertStatement.getIntoClause().isExplicitIdInsertion()) {
      // We need to generate ids as part of this bulk insert.
      //
      // Note that this is only supported for sequence-style generators and
      // post-insert-style generators; basically, only in-db generators
      IdentifierGenerator generator = persister.getIdentifierGenerator();
      if (!supportsIdGenWithBulkInsertion(generator)) {
        throw new QueryException(
            "can only generate ids as part of bulk insert with either sequence or post-insert style generators");
      }

      AST idSelectExprNode = null;

      if (SequenceGenerator.class.isAssignableFrom(generator.getClass())) {
        String seqName = (String) ((SequenceGenerator) generator).generatorKey();
        String nextval =
            sessionFactoryHelper.getFactory().getDialect().getSelectSequenceNextValString(seqName);
        idSelectExprNode = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, nextval);
      } else {
        // Don't need this, because we should never ever be selecting no columns in an insert ...
        // select...
        // and because it causes a bug on DB2
        /*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();
        if ( idInsertString != null ) {
        	idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );
        }*/
      }

      if (idSelectExprNode != null) {
        AST currentFirstSelectExprNode = selectClause.getFirstChild();
        selectClause.setFirstChild(idSelectExprNode);
        idSelectExprNode.setNextSibling(currentFirstSelectExprNode);

        insertStatement.getIntoClause().prependIdColumnSpec();
      }
    }

    final boolean includeVersionProperty =
        persister.isVersioned()
            && !insertStatement.getIntoClause().isExplicitVersionInsertion()
            && persister.isVersionPropertyInsertable();
    if (includeVersionProperty) {
      // We need to seed the version value as part of this bulk insert
      VersionType versionType = persister.getVersionType();
      AST versionValueNode = null;

      if (sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect()) {
        versionValueNode = getASTFactory().create(HqlSqlTokenTypes.PARAM, "?");
        ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification(versionType);
        ((ParameterNode) versionValueNode).setHqlParameterSpecification(paramSpec);
        parameters.add(0, paramSpec);
      } else {
        if (isIntegral(versionType)) {
          try {
            Object seedValue = versionType.seed(null);
            versionValueNode =
                getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString());
          } catch (Throwable t) {
            throw new QueryException(
                "could not determine seed value for version on bulk insert [" + versionType + "]");
          }
        } else if (isDatabaseGeneratedTimestamp(versionType)) {
          String functionName =
              sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
          versionValueNode = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, functionName);
        } else {
          throw new QueryException(
              "cannot handle version type ["
                  + versionType
                  + "] on bulk inserts with dialects not supporting parameters in insert-select statements");
        }
      }

      AST currentFirstSelectExprNode = selectClause.getFirstChild();
      selectClause.setFirstChild(versionValueNode);
      versionValueNode.setNextSibling(currentFirstSelectExprNode);

      insertStatement.getIntoClause().prependVersionColumnSpec();
    }

    if (insertStatement.getIntoClause().isDiscriminated()) {
      String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
      AST discrimValue = getASTFactory().create(HqlSqlTokenTypes.SQL_TOKEN, sqlValue);
      insertStatement.getSelectClause().addChild(discrimValue);
    }
  }
 public static boolean supportsIdGenWithBulkInsertion(IdentifierGenerator generator) {
   return SequenceGenerator.class.isAssignableFrom(generator.getClass())
       || PostInsertIdentifierGenerator.class.isAssignableFrom(generator.getClass());
 }
  public SessionFactoryImpl(
      Configuration cfg,
      Mapping mapping,
      Settings settings,
      EventListeners listeners,
      SessionFactoryObserver observer)
      throws HibernateException {
    log.info("building session factory");

    Statistics concurrentStatistics = null;
    try {
      Class concurrentStatsClass =
          ReflectHelper.classForName("org.hibernate.stat.ConcurrentStatisticsImpl");
      Constructor constructor =
          concurrentStatsClass.getConstructor(new Class[] {SessionFactoryImplementor.class});
      concurrentStatistics = (Statistics) constructor.newInstance(new Object[] {this});
      log.trace("JDK 1.5 concurrent classes present");
    } catch (NoClassDefFoundError noJava5) {
      log.trace("JDK 1.5 concurrent classes missing");
    } catch (Exception noJava5) {
      log.trace("JDK 1.5 concurrent classes missing");
    }

    if (concurrentStatistics != null) {
      this.statistics = concurrentStatistics;
    } else {
      this.statistics = new StatisticsImpl(this);
    }

    if (log.isTraceEnabled()) {
      log.trace("Statistics initialized with " + statistics.getClass().getName());
    }

    this.properties = new Properties();
    this.properties.putAll(cfg.getProperties());
    this.interceptor = cfg.getInterceptor();
    this.settings = settings;
    this.sqlFunctionRegistry =
        new SQLFunctionRegistry(settings.getDialect(), cfg.getSqlFunctions());
    this.eventListeners = listeners;
    this.observer =
        observer != null
            ? observer
            : new SessionFactoryObserver() {
              public void sessionFactoryCreated(SessionFactory factory) {}

              public void sessionFactoryClosed(SessionFactory factory) {}
            };

    this.filters = new HashMap();
    this.filters.putAll(cfg.getFilterDefinitions());

    if (log.isDebugEnabled()) {
      log.debug("Session factory constructed with filter configurations : " + filters);
    }

    if (log.isDebugEnabled()) {
      log.debug("instantiating session factory with properties: " + properties);
    }

    // Caches
    settings.getRegionFactory().start(settings, properties);

    // Generators:

    identifierGenerators = new HashMap();
    Iterator classes = cfg.getClassMappings();
    while (classes.hasNext()) {
      PersistentClass model = (PersistentClass) classes.next();
      if (!model.isInherited()) {
        IdentifierGenerator generator =
            model
                .getIdentifier()
                .createIdentifierGenerator(
                    cfg.getIdentifierGeneratorFactory(),
                    settings.getDialect(),
                    settings.getDefaultCatalogName(),
                    settings.getDefaultSchemaName(),
                    (RootClass) model);
        identifierGenerators.put(model.getEntityName(), generator);
      }
    }

    ///////////////////////////////////////////////////////////////////////
    // Prepare persisters and link them up with their cache
    // region/access-strategy

    final String cacheRegionPrefix =
        settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + ".";

    entityPersisters = new HashMap();
    Map entityAccessStrategies = new HashMap();
    Map classMeta = new HashMap();
    classes = cfg.getClassMappings();
    while (classes.hasNext()) {
      final PersistentClass model = (PersistentClass) classes.next();
      model.prepareTemporaryTables(mapping, settings.getDialect());
      final String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName();
      // cache region is defined by the root-class in the hierarchy...
      EntityRegionAccessStrategy accessStrategy =
          (EntityRegionAccessStrategy) entityAccessStrategies.get(cacheRegionName);
      if (accessStrategy == null && settings.isSecondLevelCacheEnabled()) {
        final AccessType accessType = AccessType.parse(model.getCacheConcurrencyStrategy());
        if (accessType != null) {
          log.trace("Building cache for entity data [" + model.getEntityName() + "]");
          EntityRegion entityRegion =
              settings
                  .getRegionFactory()
                  .buildEntityRegion(
                      cacheRegionName, properties, CacheDataDescriptionImpl.decode(model));
          accessStrategy = entityRegion.buildAccessStrategy(accessType);
          entityAccessStrategies.put(cacheRegionName, accessStrategy);
          allCacheRegions.put(cacheRegionName, entityRegion);
        }
      }
      EntityPersister cp =
          PersisterFactory.createClassPersister(model, accessStrategy, this, mapping);
      entityPersisters.put(model.getEntityName(), cp);
      classMeta.put(model.getEntityName(), cp.getClassMetadata());
    }
    classMetadata = Collections.unmodifiableMap(classMeta);

    Map tmpEntityToCollectionRoleMap = new HashMap();
    collectionPersisters = new HashMap();
    Iterator collections = cfg.getCollectionMappings();
    while (collections.hasNext()) {
      Collection model = (Collection) collections.next();
      final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
      final AccessType accessType = AccessType.parse(model.getCacheConcurrencyStrategy());
      CollectionRegionAccessStrategy accessStrategy = null;
      if (accessType != null && settings.isSecondLevelCacheEnabled()) {
        log.trace("Building cache for collection data [" + model.getRole() + "]");
        CollectionRegion collectionRegion =
            settings
                .getRegionFactory()
                .buildCollectionRegion(
                    cacheRegionName, properties, CacheDataDescriptionImpl.decode(model));
        accessStrategy = collectionRegion.buildAccessStrategy(accessType);
        entityAccessStrategies.put(cacheRegionName, accessStrategy);
        allCacheRegions.put(cacheRegionName, collectionRegion);
      }
      CollectionPersister persister =
          PersisterFactory.createCollectionPersister(cfg, model, accessStrategy, this);
      collectionPersisters.put(model.getRole(), persister.getCollectionMetadata());
      Type indexType = persister.getIndexType();
      if (indexType != null && indexType.isAssociationType() && !indexType.isAnyType()) {
        String entityName = ((AssociationType) indexType).getAssociatedEntityName(this);
        Set roles = (Set) tmpEntityToCollectionRoleMap.get(entityName);
        if (roles == null) {
          roles = new HashSet();
          tmpEntityToCollectionRoleMap.put(entityName, roles);
        }
        roles.add(persister.getRole());
      }
      Type elementType = persister.getElementType();
      if (elementType.isAssociationType() && !elementType.isAnyType()) {
        String entityName = ((AssociationType) elementType).getAssociatedEntityName(this);
        Set roles = (Set) tmpEntityToCollectionRoleMap.get(entityName);
        if (roles == null) {
          roles = new HashSet();
          tmpEntityToCollectionRoleMap.put(entityName, roles);
        }
        roles.add(persister.getRole());
      }
    }
    collectionMetadata = Collections.unmodifiableMap(collectionPersisters);
    Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
    while (itr.hasNext()) {
      final Map.Entry entry = (Map.Entry) itr.next();
      entry.setValue(Collections.unmodifiableSet((Set) entry.getValue()));
    }
    collectionRolesByEntityParticipant = Collections.unmodifiableMap(tmpEntityToCollectionRoleMap);

    // Named Queries:
    namedQueries = new HashMap(cfg.getNamedQueries());
    namedSqlQueries = new HashMap(cfg.getNamedSQLQueries());
    sqlResultSetMappings = new HashMap(cfg.getSqlResultSetMappings());
    imports = new HashMap(cfg.getImports());

    // after *all* persisters and named queries are registered
    Iterator iter = entityPersisters.values().iterator();
    while (iter.hasNext()) {
      final EntityPersister persister = ((EntityPersister) iter.next());
      persister.postInstantiate();
      registerEntityNameResolvers(persister);
    }
    iter = collectionPersisters.values().iterator();
    while (iter.hasNext()) {
      final CollectionPersister persister = ((CollectionPersister) iter.next());
      persister.postInstantiate();
    }

    // JNDI + Serialization:

    name = settings.getSessionFactoryName();
    try {
      uuid = (String) UUID_GENERATOR.generate(null, null);
    } catch (Exception e) {
      throw new AssertionFailure("Could not generate UUID");
    }
    SessionFactoryObjectFactory.addInstance(uuid, name, this, properties);

    log.debug("instantiated session factory");

    if (settings.isAutoCreateSchema()) {
      new SchemaExport(cfg, settings).create(false, true);
    }
    if (settings.isAutoUpdateSchema()) {
      new SchemaUpdate(cfg, settings).execute(false, true);
    }
    if (settings.isAutoValidateSchema()) {
      new SchemaValidator(cfg, settings).validate();
    }
    if (settings.isAutoDropSchema()) {
      schemaExport = new SchemaExport(cfg, settings);
    }

    if (settings.getTransactionManagerLookup() != null) {
      log.debug("obtaining JTA TransactionManager");
      transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties);
    } else {
      if (settings.getTransactionFactory().isTransactionManagerRequired()) {
        throw new HibernateException(
            "The chosen transaction strategy requires access to the JTA TransactionManager");
      }
      transactionManager = null;
    }

    currentSessionContext = buildCurrentSessionContext();

    if (settings.isQueryCacheEnabled()) {
      updateTimestampsCache = new UpdateTimestampsCache(settings, properties);
      queryCache =
          settings
              .getQueryCacheFactory()
              .getQueryCache(null, updateTimestampsCache, settings, properties);
      queryCaches = new HashMap();
      allCacheRegions.put(
          updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion());
      allCacheRegions.put(queryCache.getRegion().getName(), queryCache.getRegion());
    } else {
      updateTimestampsCache = null;
      queryCache = null;
      queryCaches = null;
    }

    // checking for named queries
    if (settings.isNamedQueryStartupCheckingEnabled()) {
      Map errors = checkNamedQueries();
      if (!errors.isEmpty()) {
        Set keys = errors.keySet();
        StringBuffer failingQueries = new StringBuffer("Errors in named queries: ");
        for (Iterator iterator = keys.iterator(); iterator.hasNext(); ) {
          String queryName = (String) iterator.next();
          HibernateException e = (HibernateException) errors.get(queryName);
          failingQueries.append(queryName);
          if (iterator.hasNext()) {
            failingQueries.append(", ");
          }
          log.error("Error in named query: " + queryName, e);
        }
        throw new HibernateException(failingQueries.toString());
      }
    }

    // stats
    getStatistics().setStatisticsEnabled(settings.isStatisticsEnabled());

    // EntityNotFoundDelegate
    EntityNotFoundDelegate entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
    if (entityNotFoundDelegate == null) {
      entityNotFoundDelegate =
          new EntityNotFoundDelegate() {
            public void handleEntityNotFound(String entityName, Serializable id) {
              throw new ObjectNotFoundException(id, entityName);
            }

            public boolean isEntityNotFoundException(RuntimeException exception) {
              return ObjectNotFoundException.class.isInstance(exception);
            }
          };
    }
    this.entityNotFoundDelegate = entityNotFoundDelegate;

    // this needs to happen after persisters are all ready to go...
    this.fetchProfiles = new HashMap();
    itr = cfg.iterateFetchProfiles();
    while (itr.hasNext()) {
      final org.hibernate.mapping.FetchProfile mappingProfile =
          (org.hibernate.mapping.FetchProfile) itr.next();
      final FetchProfile fetchProfile = new FetchProfile(mappingProfile.getName());
      Iterator fetches = mappingProfile.getFetches().iterator();
      while (fetches.hasNext()) {
        final org.hibernate.mapping.FetchProfile.Fetch mappingFetch =
            (org.hibernate.mapping.FetchProfile.Fetch) fetches.next();
        // resolve the persister owning the fetch
        final String entityName = getImportedClassName(mappingFetch.getEntity());
        final EntityPersister owner =
            (EntityPersister) (entityName == null ? null : entityPersisters.get(entityName));
        if (owner == null) {
          throw new HibernateException(
              "Unable to resolve entity reference ["
                  + mappingFetch.getEntity()
                  + "] in fetch profile ["
                  + fetchProfile.getName()
                  + "]");
        }

        // validate the specified association fetch
        Type associationType = owner.getPropertyType(mappingFetch.getAssociation());
        if (associationType == null || !associationType.isAssociationType()) {
          throw new HibernateException(
              "Fetch profile [" + fetchProfile.getName() + "] specified an invalid association");
        }

        // resolve the style
        final Fetch.Style fetchStyle = Fetch.Style.parse(mappingFetch.getStyle());

        // then construct the fetch instance...
        fetchProfile.addFetch(new Association(owner, mappingFetch.getAssociation()), fetchStyle);
        ((Loadable) owner).registerAffectingFetchProfile(fetchProfile.getName());
      }
      fetchProfiles.put(fetchProfile.getName(), fetchProfile);
    }

    this.observer.sessionFactoryCreated(this);
  }