/** Convience method to retreive an entities next version value */
  private Object getNextVersion(FlushEntityEvent event) throws HibernateException {

    EntityEntry entry = event.getEntityEntry();
    EntityPersister persister = entry.getPersister();
    if (persister.isVersioned()) {

      Object[] values = event.getPropertyValues();

      if (entry.isBeingReplicated()) {
        return Versioning.getVersion(values, persister);
      } else {
        int[] dirtyProperties = event.getDirtyProperties();

        final boolean isVersionIncrementRequired =
            isVersionIncrementRequired(event, entry, persister, dirtyProperties);

        final Object nextVersion =
            isVersionIncrementRequired
                ? Versioning.increment(
                    entry.getVersion(), persister.getVersionType(), event.getSession())
                : entry.getVersion(); // use the current version

        Versioning.setVersion(values, nextVersion, persister);

        return nextVersion;
      }
    } else {
      return null;
    }
  }
  FromElement addFromElement() throws SemanticException {
    FromClause parentFromClause = fromClause.getParentFromClause();
    if (parentFromClause != null) {
      // Look up class name using the first identifier in the path.
      String pathAlias = PathHelper.getAlias(path);
      FromElement parentFromElement = parentFromClause.getFromElement(pathAlias);
      if (parentFromElement != null) {
        return createFromElementInSubselect(path, pathAlias, parentFromElement, classAlias);
      }
    }

    EntityPersister entityPersister =
        fromClause.getSessionFactoryHelper().requireClassPersister(path);

    FromElement elem =
        createAndAddFromElement(
            path,
            classAlias,
            entityPersister,
            (EntityType) ((Queryable) entityPersister).getType(),
            null);

    // Add to the query spaces.
    fromClause.getWalker().addQuerySpaces(entityPersister.getQuerySpaces());

    return elem;
  }
  /**
   * Flushes a single entity's state to the database, by scheduling an update action, if necessary
   */
  public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
    final Object entity = event.getEntity();
    final EntityEntry entry = event.getEntityEntry();
    final EventSource session = event.getSession();
    final EntityPersister persister = entry.getPersister();
    final Status status = entry.getStatus();
    final EntityMode entityMode = session.getEntityMode();
    final Type[] types = persister.getPropertyTypes();

    final boolean mightBeDirty = entry.requiresDirtyCheck(entity);

    final Object[] values = getValues(entity, entry, entityMode, mightBeDirty, session);

    event.setPropertyValues(values);

    // TODO: avoid this for non-new instances where mightBeDirty==false
    boolean substitute = wrapCollections(session, persister, types, values);

    if (isUpdateNecessary(event, mightBeDirty)) {
      substitute = scheduleUpdate(event) || substitute;
    }

    if (status != Status.DELETED) {
      // now update the object .. has to be outside the main if block above (because of collections)
      if (substitute) persister.setPropertyValues(entity, values, entityMode);

      // Search for collections by reachability, updating their role.
      // We don't want to touch collections reachable from a deleted object
      if (persister.hasCollections()) {
        new FlushVisitor(session, entity).processEntityPropertyValues(values, types);
      }
    }
  }
 private void checkNaturalId(
     EntityPersister persister,
     EntityEntry entry,
     Object[] current,
     Object[] loaded,
     EntityMode entityMode,
     SessionImplementor session) {
   if (persister.hasNaturalIdentifier() && entry.getStatus() != Status.READ_ONLY) {
     Object[] snapshot = null;
     Type[] types = persister.getPropertyTypes();
     int[] props = persister.getNaturalIdentifierProperties();
     boolean[] updateable = persister.getPropertyUpdateability();
     for (int i = 0; i < props.length; i++) {
       int prop = props[i];
       if (!updateable[prop]) {
         Object loadedVal;
         if (loaded == null) {
           if (snapshot == null) {
             snapshot =
                 session.getPersistenceContext().getNaturalIdSnapshot(entry.getId(), persister);
           }
           loadedVal = snapshot[i];
         } else {
           loadedVal = loaded[prop];
         }
         if (!types[prop].isEqual(current[prop], loadedVal, entityMode)) {
           throw new HibernateException(
               "immutable natural identifier of an instance of "
                   + persister.getEntityName()
                   + " was altered");
         }
       }
     }
   }
 }
        public void noCascade(
            EventSource session,
            Object child,
            Object parent,
            EntityPersister persister,
            int propertyIndex) {
          if (child == null) {
            return;
          }
          Type type = persister.getPropertyTypes()[propertyIndex];
          if (type.isEntityType()) {
            String childEntityName =
                ((EntityType) type).getAssociatedEntityName(session.getFactory());

            if (!isInManagedState(child, session)
                && !(child
                    instanceof
                    HibernateProxy) // a proxy cannot be transient and it breaks
                                    // ForeignKeys.isTransient
                && ForeignKeys.isTransient(childEntityName, child, null, session)) {
              String parentEntiytName = persister.getEntityName();
              String propertyName = persister.getPropertyNames()[propertyIndex];
              throw new TransientObjectException(
                  "object references an unsaved transient instance - "
                      + "save the transient instance before flushing: "
                      + parentEntiytName
                      + "."
                      + propertyName
                      + " -> "
                      + childEntityName);
            }
          }
        }
  public Object[] getNaturalIdSnapshot(Serializable id, EntityPersister persister)
      throws HibernateException {
    if (!persister.hasNaturalIdentifier()) {
      return null;
    }

    // if the natural-id is marked as non-mutable, it is not retrieved during a
    // normal database-snapshot operation...
    int[] props = persister.getNaturalIdentifierProperties();
    boolean[] updateable = persister.getPropertyUpdateability();
    boolean allNatualIdPropsAreUpdateable = true;
    for (int i = 0; i < props.length; i++) {
      if (!updateable[props[i]]) {
        allNatualIdPropsAreUpdateable = false;
        break;
      }
    }

    if (allNatualIdPropsAreUpdateable) {
      // do this when all the properties are updateable since there is
      // a certain likelihood that the information will already be
      // snapshot-cached.
      Object[] entitySnapshot = getDatabaseSnapshot(id, persister);
      if (entitySnapshot == NO_ROW) {
        return null;
      }
      Object[] naturalIdSnapshot = new Object[props.length];
      for (int i = 0; i < props.length; i++) {
        naturalIdSnapshot[i] = entitySnapshot[props[i]];
      }
      return naturalIdSnapshot;
    } else {
      return persister.getNaturalIdentifierSnapshot(id, session);
    }
  }
  /**
   * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy and
   * overwrite the registration of the old one. This breaks == and occurs only for "class" proxies
   * rather than "interface" proxies. Also init the proxy to point to the given target
   * implementation if necessary.
   *
   * @param proxy The proxy instance to be narrowed.
   * @param persister The persister for the proxied entity.
   * @param key The internal cache key for the proxied entity.
   * @param object (optional) the actual proxied entity instance.
   * @return An appropriately narrowed instance.
   * @throws HibernateException
   */
  public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object)
      throws HibernateException {

    boolean alreadyNarrow =
        persister.getConcreteProxyClass(session.getEntityMode()).isAssignableFrom(proxy.getClass());

    if (!alreadyNarrow) {
      if (PROXY_WARN_LOG.isWarnEnabled()) {
        PROXY_WARN_LOG.warn(
            "Narrowing proxy to "
                + persister.getConcreteProxyClass(session.getEntityMode())
                + " - this operation breaks ==");
      }

      if (object != null) {
        proxiesByKey.remove(key);
        return object; // return the proxied object
      } else {
        proxy = persister.createProxy(key.getIdentifier(), session);
        proxiesByKey.put(key, proxy); // overwrite old proxy
        return proxy;
      }

    } else {

      if (object != null) {
        LazyInitializer li = ((HibernateProxy) proxy).getHibernateLazyInitializer();
        li.setImplementation(object);
      }

      return proxy;
    }
  }
  /**
   * Search the persistence context for an owner for the child object, given a collection role. If
   * <tt>mergeMap</tt> is non-null, also check the detached graph being merged for a parent.
   */
  public Serializable getOwnerId(String entity, String property, Object childEntity, Map mergeMap) {

    EntityPersister persister = session.getFactory().getEntityPersister(entity);
    final CollectionPersister collectionPersister =
        session.getFactory().getCollectionPersister(entity + '.' + property);

    Iterator entities = entityEntries.entrySet().iterator();
    while (entities.hasNext()) {
      Map.Entry me = (Map.Entry) entities.next();
      EntityEntry ee = (EntityEntry) me.getValue();
      if (persister.isSubclassEntityName(ee.getEntityName())) {
        Object instance = me.getKey();

        // check if the managed object is the parent
        boolean found =
            isFoundInParent(property, childEntity, persister, collectionPersister, instance);

        if (!found && mergeMap != null) {
          // check if the detached object being merged is the parent
          Object unmergedInstance = mergeMap.get(instance);
          Object unmergedChild = mergeMap.get(childEntity);
          if (unmergedInstance != null && unmergedChild != null) {
            found =
                isFoundInParent(
                    property, unmergedChild, persister, collectionPersister, unmergedInstance);
          }
        }

        if (found) {
          return ee.getId();
        }
      }
    }
    return null;
  }
  @SuppressWarnings("unchecked")
  @Override
  /**
   * Handle the given delete event. This is the cascaded form.
   *
   * @param event The delete event.
   * @param transientEntities The cache of entities already deleted
   * @throws HibernateException
   */
  public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
    final EventSource source = event.getSession();

    final PersistenceContext persistenceContext = source.getPersistenceContext();
    Object entity = persistenceContext.unproxyAndReassociate(event.getObject());
    EntityEntry entityEntry = persistenceContext.getEntry(entity);

    final EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
    final Object version;

    if (persister.isVersioned()) {
      version = persister.getVersion(entity, source.getEntityMode());
      // Make sure version has not changed on deleted entities
      if ((entity instanceof TimelineEntity) && !((TimelineEntity) entity).isNew()) {
        if (!persister.getVersionType().isEqual(version, entityEntry.getVersion())) {
          throw new StaleObjectStateException(persister.getEntityName(), entityEntry.getId());
        }
      }
    }
    super.onDelete(event, transientEntities);
  }
  /** make sure user didn't mangle the id */
  public void checkId(
      Object object,
      EntityPersister persister,
      Serializable id,
      EntityMode entityMode,
      SessionImplementor session)
      throws HibernateException {

    if (id != null && id instanceof DelayedPostInsertIdentifier) {
      // this is a situation where the entity id is assigned by a post-insert generator
      // and was saved outside the transaction forcing it to be delayed
      return;
    }

    if (persister.canExtractIdOutOfEntity()) {

      Serializable oid = persister.getIdentifier(object, session);
      if (id == null) {
        throw new AssertionFailure(
            "null id in "
                + persister.getEntityName()
                + " entry (don't flush the Session after an exception occurs)");
      }
      if (!persister.getIdentifierType().isEqual(id, oid, entityMode, session.getFactory())) {
        throw new HibernateException(
            "identifier of an instance of "
                + persister.getEntityName()
                + " was altered from "
                + id
                + " to "
                + oid);
      }
    }
  }
  /**
   * Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
   *
   * <p>Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
   * to resolve any associations yet, because there might be other entities waiting to be read from
   * the JDBC result set we are currently processing
   */
  public static void postHydrate(
      final EntityPersister persister,
      final Serializable id,
      final Object[] values,
      final Object rowId,
      final Object object,
      final LockMode lockMode,
      final boolean lazyPropertiesAreUnfetched,
      final SessionImplementor session)
      throws HibernateException {

    Object version = Versioning.getVersion(values, persister);
    session
        .getPersistenceContext()
        .addEntry(
            object,
            Status.LOADING,
            values,
            rowId,
            id,
            version,
            lockMode,
            true,
            persister,
            false,
            lazyPropertiesAreUnfetched);

    if (log.isTraceEnabled() && version != null) {
      String versionStr =
          persister.isVersioned()
              ? persister.getVersionType().toLoggableString(version, session.getFactory())
              : "null";
      log.trace("Version: " + versionStr);
    }
  }
  /**
   * Handle the given lock event.
   *
   * @param event The lock event to be handled.
   * @throws HibernateException
   */
  public void onLock(LockEvent event) throws HibernateException {

    if (event.getObject() == null) {
      throw new NullPointerException("attempted to lock null");
    }

    if (event.getLockMode() == LockMode.WRITE) {
      throw new HibernateException("Invalid lock mode for lock()");
    }

    SessionImplementor source = event.getSession();

    Object entity = source.getPersistenceContext().unproxyAndReassociate(event.getObject());
    // TODO: if object was an uninitialized proxy, this is inefficient,
    //      resulting in two SQL selects

    EntityEntry entry = source.getPersistenceContext().getEntry(entity);
    if (entry == null) {
      final EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
      final Serializable id = persister.getIdentifier(entity, source.getEntityMode());
      if (!ForeignKeys.isNotTransient(event.getEntityName(), entity, Boolean.FALSE, source)) {
        throw new TransientObjectException(
            "cannot lock an unsaved transient instance: " + persister.getEntityName());
      }

      entry = reassociate(event, entity, id, persister);

      cascadeOnLock(event, persister, entity);
    }

    upgradeLock(entity, entry, event.getLockMode(), source);
  }
Example #13
0
 public void forceLocked(Object entity, Object nextVersion) {
   version = nextVersion;
   loadedState[persister.getVersionProperty()] = version;
   //noinspection deprecation
   setLockMode(LockMode.FORCE); // TODO:  use LockMode.PESSIMISTIC_FORCE_INCREMENT
   persister.setPropertyValue(entity, getPersister().getVersionProperty(), nextVersion);
 }
  @Override
  public void doAfterTransactionCompletion(boolean success, SessionImplementor session)
      throws CacheException {
    final EntityPersister persister = getPersister();
    if (persister.hasCache()) {
      final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
      final Object ck =
          cache.generateCacheKey(
              getId(), persister, session.getFactory(), session.getTenantIdentifier());

      if (success && cacheEntry != null /*!persister.isCacheInvalidationRequired()*/) {
        final boolean put = cacheAfterUpdate(cache, ck);

        if (put && getSession().getFactory().getStatistics().isStatisticsEnabled()) {
          getSession()
              .getFactory()
              .getStatisticsImplementor()
              .secondLevelCachePut(cache.getRegion().getName());
        }
      } else {
        cache.unlockItem(session, ck, lock);
      }
    }
    postCommitUpdate(success);
  }
  /**
   * 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);
    }
  }
  /** Search the persistence context for an index of the child object, given a collection role */
  public Object getIndexInOwner(String entity, String property, Object childEntity, Map mergeMap) {

    EntityPersister persister = session.getFactory().getEntityPersister(entity);
    CollectionPersister cp = session.getFactory().getCollectionPersister(entity + '.' + property);
    Iterator entities = entityEntries.entrySet().iterator();
    while (entities.hasNext()) {
      Map.Entry me = (Map.Entry) entities.next();
      EntityEntry ee = (EntityEntry) me.getValue();
      if (persister.isSubclassEntityName(ee.getEntityName())) {
        Object instance = me.getKey();

        Object index = getIndexInParent(property, childEntity, persister, cp, instance);

        if (index == null && mergeMap != null) {
          Object unmergedInstance = mergeMap.get(instance);
          Object unmergedChild = mergeMap.get(childEntity);
          if (unmergedInstance != null && unmergedChild != null) {
            index = getIndexInParent(property, unmergedChild, persister, cp, unmergedInstance);
          }
        }

        if (index != null) return index;
      }
    }
    return null;
  }
  private Object[] getValues(
      Object entity,
      EntityEntry entry,
      EntityMode entityMode,
      boolean mightBeDirty,
      SessionImplementor session) {
    final Object[] loadedState = entry.getLoadedState();
    final Status status = entry.getStatus();
    final EntityPersister persister = entry.getPersister();

    final Object[] values;
    if (status == Status.DELETED) {
      // grab its state saved at deletion
      values = entry.getDeletedState();
    } else if (!mightBeDirty && loadedState != null) {
      values = loadedState;
    } else {
      checkId(entity, persister, entry.getId(), entityMode, session);

      // grab its current state
      values = persister.getPropertyValues(entity, entityMode);

      checkNaturalId(persister, entry, values, loadedState, entityMode, session);
    }
    return values;
  }
 private CacheKey buildCacheKey(Serializable identifier, EntityPersister p) {
   return new CacheKey(
       identifier,
       p.getIdentifierType(),
       p.getRootEntityName(),
       EntityMode.POJO,
       SessionFactoryImpl.this);
 }
 public void evictEntityRegion(String entityName) {
   EntityPersister p = getEntityPersister(entityName);
   if (p.hasCache()) {
     if (log.isDebugEnabled()) {
       log.debug("evicting second-level cache: " + p.getEntityName());
     }
     p.getCacheAccessStrategy().evictAll();
   }
 }
  FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
    FromElement elem;

    implied =
        true; // TODO: always true for now, but not if we later decide to support elements() in the
              // from clause
    inElementsFunction = true;
    Type elementType = queryableCollection.getElementType();
    if (!elementType.isEntityType()) {
      throw new IllegalArgumentException(
          "Cannot create element join for a collection of non-entities!");
    }
    this.queryableCollection = queryableCollection;
    SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
    FromElement destination = null;
    String tableAlias = null;
    EntityPersister entityPersister = queryableCollection.getElementPersister();
    tableAlias = fromClause.getAliasGenerator().createName(entityPersister.getEntityName());
    String associatedEntityName = entityPersister.getEntityName();
    EntityPersister targetEntityPersister = sfh.requireClassPersister(associatedEntityName);
    // Create the FROM element for the target (the elements of the collection).
    destination =
        createAndAddFromElement(
            associatedEntityName,
            classAlias,
            targetEntityPersister,
            (EntityType) queryableCollection.getElementType(),
            tableAlias);
    // If the join is implied, then don't include sub-classes on the element.
    if (implied) {
      destination.setIncludeSubclasses(false);
    }
    fromClause.addCollectionJoinFromElementByPath(path, destination);
    //		origin.addDestination(destination);
    // Add the query spaces.
    fromClause.getWalker().addQuerySpaces(entityPersister.getQuerySpaces());

    CollectionType type = queryableCollection.getCollectionType();
    String role = type.getRole();
    String roleAlias = origin.getTableAlias();

    String[] targetColumns = sfh.getCollectionElementColumns(role, roleAlias);
    AssociationType elementAssociationType = sfh.getElementAssociationType(type);

    // Create the join element under the from element.
    int joinType = JoinFragment.INNER_JOIN;
    JoinSequence joinSequence =
        sfh.createJoinSequence(
            implied, elementAssociationType, tableAlias, joinType, targetColumns);
    elem = initializeJoin(path, destination, joinSequence, targetColumns, origin, false);
    elem.setUseFromFragment(
        true); // The associated entity is implied, but it must be included in the FROM.
    elem.setCollectionTableAlias(roleAlias); // The collection alias is the role.
    return elem;
  }
  /**
   * Reads the entity hosting the association from the datastore and applies any property changes
   * from the server side.
   */
  private void updateHostingEntityIfRequired() {
    if (hostingEntity != null && hostingEntityRequiresReadAfterUpdate()) {
      EntityPersister entityPersister = getHostingEntityPersister();

      entityPersister.processUpdateGeneratedProperties(
          entityPersister.getIdentifier(hostingEntity, session),
          hostingEntity,
          new Object[entityPersister.getPropertyNames().length],
          session);
    }
  }
 private void registerEntityNameResolvers(EntityPersister persister) {
   if (persister.getEntityMetamodel() == null
       || persister.getEntityMetamodel().getTuplizerMapping() == null) {
     return;
   }
   Iterator itr = persister.getEntityMetamodel().getTuplizerMapping().iterateTuplizers();
   while (itr.hasNext()) {
     final EntityTuplizer tuplizer = (EntityTuplizer) itr.next();
     registerEntityNameResolvers(tuplizer);
   }
 }
 public void evictEntity(String entityName, Serializable identifier) {
   EntityPersister p = getEntityPersister(entityName);
   if (p.hasCache()) {
     if (log.isDebugEnabled()) {
       log.debug(
           "evicting second-level cache: "
               + MessageHelper.infoString(p, identifier, SessionFactoryImpl.this));
     }
     p.getCacheAccessStrategy().evict(buildCacheKey(identifier, p));
   }
 }
  /**
   * Closes the session factory, releasing all held resources.
   *
   * <ol>
   *   <li>cleans up used cache regions and "stops" the cache provider.
   *   <li>close the JDBC connection
   *   <li>remove the JNDI binding
   * </ol>
   *
   * Note: Be aware that the sessionfactory instance still can be a "heavy" object memory wise after
   * close() has been called. Thus it is important to not keep referencing the instance to let the
   * garbage collector release the memory.
   */
  public void close() throws HibernateException {

    if (isClosed) {
      log.trace("already closed");
      return;
    }

    log.info("closing");

    isClosed = true;

    Iterator iter = entityPersisters.values().iterator();
    while (iter.hasNext()) {
      EntityPersister p = (EntityPersister) iter.next();
      if (p.hasCache()) {
        p.getCacheAccessStrategy().getRegion().destroy();
      }
    }

    iter = collectionPersisters.values().iterator();
    while (iter.hasNext()) {
      CollectionPersister p = (CollectionPersister) iter.next();
      if (p.hasCache()) {
        p.getCacheAccessStrategy().getRegion().destroy();
      }
    }

    if (settings.isQueryCacheEnabled()) {
      queryCache.destroy();

      iter = queryCaches.values().iterator();
      while (iter.hasNext()) {
        QueryCache cache = (QueryCache) iter.next();
        cache.destroy();
      }
      updateTimestampsCache.destroy();
    }

    settings.getRegionFactory().stop();

    if (settings.isAutoDropSchema()) {
      schemaExport.drop(false, true);
    }

    try {
      settings.getConnectionProvider().close();
    } finally {
      SessionFactoryObjectFactory.removeInstance(uuid, name, properties);
    }

    observer.sessionFactoryClosed(this);
    eventListeners.destroyListeners();
  }
 @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());
 }
 private void synchronizePersisterState(Object entity, EntityPersister persister, Object[] state) {
   String[] propertyNames = persister.getPropertyNames();
   for (int i = 0; i < propertyNames.length; i++) {
     String p = propertyNames[i];
     MetaProperty metaProperty = domainMetaClass.getMetaProperty(p);
     if (ClosureEventTriggeringInterceptor.IGNORED.contains(p) || metaProperty == null) {
       continue;
     }
     Object value = metaProperty.getProperty(entity);
     state[i] = value;
     persister.setPropertyValue(entity, i, value);
   }
 }
  public FromElement createEntityJoin(
      String entityClass,
      String tableAlias,
      JoinSequence joinSequence,
      boolean fetchFlag,
      boolean inFrom,
      EntityType type,
      String role,
      String joinPath)
      throws SemanticException {
    FromElement elem = createJoin(entityClass, tableAlias, joinSequence, type, false);
    elem.setFetch(fetchFlag);

    if (joinPath != null) {
      elem.applyTreatAsDeclarations(fromClause.getWalker().getTreatAsDeclarationsByPath(joinPath));
    }

    EntityPersister entityPersister = elem.getEntityPersister();
    int numberOfTables = entityPersister.getQuerySpaces().length;
    if (numberOfTables > 1 && implied && !elem.useFromFragment()) {
      LOG.debug("createEntityJoin() : Implied multi-table entity join");
      elem.setUseFromFragment(true);
    }

    // If this is an implied join in a FROM clause, then use ANSI-style joining, and set the
    // flag on the FromElement that indicates that it was implied in the FROM clause itself.
    if (implied && inFrom) {
      joinSequence.setUseThetaStyle(false);
      elem.setUseFromFragment(true);
      elem.setImpliedInFromClause(true);
    }
    if (elem.getWalker().isSubQuery()) {
      // two conditions where we need to transform this to a theta-join syntax:
      //      1) 'elem' is the "root from-element" in correlated subqueries
      //      2) The DotNode.useThetaStyleImplicitJoins has been set to true
      //          and 'elem' represents an implicit join
      if (elem.getFromClause() != elem.getOrigin().getFromClause()
          ||
          //			        ( implied && DotNode.useThetaStyleImplicitJoins ) ) {
          PathSeparatorNode.useThetaStyleImplicitJoins) {
        // the "root from-element" in correlated subqueries do need this piece
        elem.setType(FROM_FRAGMENT);
        joinSequence.setUseThetaStyle(true);
        elem.setUseFromFragment(false);
      }
    }

    elem.setRole(role);

    return elem;
  }
  /**
   * Construct a new key for a caching natural identifier resolutions into the second level cache.
   * Note that an entity name should always be the root entity name, not a subclass entity name.
   *
   * @param naturalIdValues The naturalIdValues associated with the cached data
   * @param persister The persister for the entity
   * @param session The originating session
   */
  public NaturalIdCacheKey(
      final Object[] naturalIdValues,
      final EntityPersister persister,
      final SessionImplementor session) {

    this.entityName = persister.getRootEntityName();
    this.tenantId = session.getTenantIdentifier();

    this.naturalIdValues = new Serializable[naturalIdValues.length];

    final SessionFactoryImplementor factory = session.getFactory();
    final int[] naturalIdPropertyIndexes = persister.getNaturalIdentifierProperties();
    final Type[] propertyTypes = persister.getPropertyTypes();

    final int prime = 31;
    int result = 1;
    result = prime * result + ((this.entityName == null) ? 0 : this.entityName.hashCode());
    result = prime * result + ((this.tenantId == null) ? 0 : this.tenantId.hashCode());
    for (int i = 0; i < naturalIdValues.length; i++) {
      final Type type = propertyTypes[naturalIdPropertyIndexes[i]];
      final Object value = naturalIdValues[i];

      result = prime * result + (value != null ? type.getHashCode(value, factory) : 0);

      this.naturalIdValues[i] = type.disassemble(value, session, null);
    }

    this.hashCode = result;
    this.toString =
        new ValueHolder<String>(
            new ValueHolder.DeferredInitializer<String>() {
              @Override
              public String initialize() {
                // Complex toString is needed as naturalIds for entities are not simply based on a
                // single value like primary keys
                // the only same way to differentiate the keys is to included the disassembled
                // values in the string.
                final StringBuilder toStringBuilder =
                    new StringBuilder(entityName).append("##NaturalId[");
                for (int i = 0; i < naturalIdValues.length; i++) {
                  toStringBuilder.append(naturalIdValues[i]);
                  if (i + 1 < naturalIdValues.length) {
                    toStringBuilder.append(", ");
                  }
                }
                toStringBuilder.append("]");

                return toStringBuilder.toString();
              }
            });
  }
 private boolean hasDirtyCollections(
     FlushEntityEvent event, EntityPersister persister, Status status) {
   if (isCollectionDirtyCheckNecessary(persister, status)) {
     DirtyCollectionSearchVisitor visitor =
         new DirtyCollectionSearchVisitor(
             event.getSession(), persister.getPropertyVersionability());
     visitor.processEntityPropertyValues(event.getPropertyValues(), persister.getPropertyTypes());
     boolean hasDirtyCollections = visitor.wasDirtyCollectionFound();
     event.setHasDirtyCollection(hasDirtyCollections);
     return hasDirtyCollections;
   } else {
     return false;
   }
 }
  /**
   * 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;
  }