Search in sources :

Example 1 with EntityUniqueKey

use of org.hibernate.engine.spi.EntityUniqueKey in project hibernate-orm by hibernate.

the class Loader method loadFromResultSet.

/**
	 * Hydrate the state an object from the SQL <tt>ResultSet</tt>, into
	 * an array or "hydrated" values (do not resolve associations yet),
	 * and pass the hydrates state to the session.
	 */
private void loadFromResultSet(final ResultSet rs, final int i, final Object object, final String instanceEntityName, final EntityKey key, final String rowIdAlias, final LockMode lockMode, final Loadable rootPersister, final SharedSessionContractImplementor session) throws SQLException, HibernateException {
    final Serializable id = key.getIdentifier();
    // Get the persister for the _subclass_
    final Loadable persister = (Loadable) getFactory().getEntityPersister(instanceEntityName);
    if (LOG.isTraceEnabled()) {
        LOG.tracef("Initializing object from ResultSet: %s", MessageHelper.infoString(persister, id, getFactory()));
    }
    boolean fetchAllPropertiesRequested = isEagerPropertyFetchEnabled(i);
    // add temp entry so that the next step is circular-reference
    // safe - only needed because some types don't take proper
    // advantage of two-phase-load (esp. components)
    TwoPhaseLoad.addUninitializedEntity(key, object, persister, lockMode, session);
    //This is not very nice (and quite slow):
    final String[][] cols = persister == rootPersister ? getEntityAliases()[i].getSuffixedPropertyAliases() : getEntityAliases()[i].getSuffixedPropertyAliases(persister);
    final Object[] values = persister.hydrate(rs, id, object, rootPersister, cols, fetchAllPropertiesRequested, session);
    final Object rowId = persister.hasRowId() ? rs.getObject(rowIdAlias) : null;
    final AssociationType[] ownerAssociationTypes = getOwnerAssociationTypes();
    if (ownerAssociationTypes != null && ownerAssociationTypes[i] != null) {
        String ukName = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName();
        if (ukName != null) {
            final int index = ((UniqueKeyLoadable) persister).getPropertyIndex(ukName);
            final Type type = persister.getPropertyTypes()[index];
            // polymorphism not really handled completely correctly,
            // perhaps...well, actually its ok, assuming that the
            // entity name used in the lookup is the same as the
            // the one used here, which it will be
            EntityUniqueKey euk = new EntityUniqueKey(//polymorphism comment above
            rootPersister.getEntityName(), ukName, type.semiResolve(values[index], session, object), type, persister.getEntityMode(), session.getFactory());
            session.getPersistenceContext().addEntity(euk, object);
        }
    }
    TwoPhaseLoad.postHydrate(persister, id, values, rowId, object, lockMode, session);
}
Also used : UniqueKeyLoadable(org.hibernate.persister.entity.UniqueKeyLoadable) Loadable(org.hibernate.persister.entity.Loadable) Serializable(java.io.Serializable) UniqueKeyLoadable(org.hibernate.persister.entity.UniqueKeyLoadable) EntityType(org.hibernate.type.EntityType) VersionType(org.hibernate.type.VersionType) AssociationType(org.hibernate.type.AssociationType) Type(org.hibernate.type.Type) AssociationType(org.hibernate.type.AssociationType) EntityUniqueKey(org.hibernate.engine.spi.EntityUniqueKey)

Example 2 with EntityUniqueKey

use of org.hibernate.engine.spi.EntityUniqueKey in project hibernate-orm by hibernate.

the class EntityReferenceInitializerImpl method loadFromResultSet.

private void loadFromResultSet(ResultSet resultSet, ResultSetProcessingContext context, Object entityInstance, String concreteEntityTypeName, EntityKey entityKey, LockMode lockModeToAcquire) {
    final Serializable id = entityKey.getIdentifier();
    // Get the persister for the _subclass_
    final Loadable concreteEntityPersister = (Loadable) context.getSession().getFactory().getMetamodel().entityPersister(concreteEntityTypeName);
    if (log.isTraceEnabled()) {
        log.tracev("Initializing object from ResultSet: {0}", MessageHelper.infoString(concreteEntityPersister, id, context.getSession().getFactory()));
    }
    // add temp entry so that the next step is circular-reference
    // safe - only needed because some types don't take proper
    // advantage of two-phase-load (esp. components)
    TwoPhaseLoad.addUninitializedEntity(entityKey, entityInstance, concreteEntityPersister, lockModeToAcquire, context.getSession());
    final EntityPersister rootEntityPersister = context.getSession().getFactory().getMetamodel().entityPersister(concreteEntityPersister.getRootEntityName());
    final Object[] values;
    try {
        values = concreteEntityPersister.hydrate(resultSet, id, entityInstance, (Loadable) entityReference.getEntityPersister(), concreteEntityPersister == rootEntityPersister ? entityReferenceAliases.getColumnAliases().getSuffixedPropertyAliases() : entityReferenceAliases.getColumnAliases().getSuffixedPropertyAliases(concreteEntityPersister), context.getLoadPlan().areLazyAttributesForceFetched(), context.getSession());
        context.getProcessingState(entityReference).registerHydratedState(values);
    } catch (SQLException e) {
        throw context.getSession().getFactory().getServiceRegistry().getService(JdbcServices.class).getSqlExceptionHelper().convert(e, "Could not read entity state from ResultSet : " + entityKey);
    }
    final Object rowId;
    try {
        rowId = concreteEntityPersister.hasRowId() ? resultSet.getObject(entityReferenceAliases.getColumnAliases().getRowIdAlias()) : null;
    } catch (SQLException e) {
        throw context.getSession().getFactory().getServiceRegistry().getService(JdbcServices.class).getSqlExceptionHelper().convert(e, "Could not read entity row-id from ResultSet : " + entityKey);
    }
    final EntityType entityType = EntityFetch.class.isInstance(entityReference) ? ((EntityFetch) entityReference).getFetchedType() : entityReference.getEntityPersister().getEntityMetamodel().getEntityType();
    if (entityType != null) {
        String ukName = entityType.getRHSUniqueKeyPropertyName();
        if (ukName != null) {
            final int index = ((UniqueKeyLoadable) concreteEntityPersister).getPropertyIndex(ukName);
            final Type type = concreteEntityPersister.getPropertyTypes()[index];
            // polymorphism not really handled completely correctly,
            // perhaps...well, actually its ok, assuming that the
            // entity name used in the lookup is the same as the
            // the one used here, which it will be
            EntityUniqueKey euk = new EntityUniqueKey(entityReference.getEntityPersister().getEntityName(), ukName, type.semiResolve(values[index], context.getSession(), entityInstance), type, concreteEntityPersister.getEntityMode(), context.getSession().getFactory());
            context.getSession().getPersistenceContext().addEntity(euk, entityInstance);
        }
    }
    TwoPhaseLoad.postHydrate(concreteEntityPersister, id, values, rowId, entityInstance, lockModeToAcquire, context.getSession());
    context.registerHydratedEntity(entityReference, entityKey, entityInstance);
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) UniqueKeyLoadable(org.hibernate.persister.entity.UniqueKeyLoadable) Loadable(org.hibernate.persister.entity.Loadable) Serializable(java.io.Serializable) SQLException(java.sql.SQLException) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) UniqueKeyLoadable(org.hibernate.persister.entity.UniqueKeyLoadable) EntityType(org.hibernate.type.EntityType) EntityFetch(org.hibernate.loader.plan.spi.EntityFetch) EntityType(org.hibernate.type.EntityType) VersionType(org.hibernate.type.VersionType) Type(org.hibernate.type.Type) EntityUniqueKey(org.hibernate.engine.spi.EntityUniqueKey)

Example 3 with EntityUniqueKey

use of org.hibernate.engine.spi.EntityUniqueKey in project hibernate-orm by hibernate.

the class EntityType method loadByUniqueKey.

/**
	 * Load an instance by a unique key that is not the primary key.
	 *
	 * @param entityName The name of the entity to load
	 * @param uniqueKeyPropertyName The name of the property defining the uniqie key.
	 * @param key The unique key property value.
	 * @param session The originating session.
	 *
	 * @return The loaded entity
	 *
	 * @throws HibernateException generally indicates problems performing the load.
	 */
public Object loadByUniqueKey(String entityName, String uniqueKeyPropertyName, Object key, SharedSessionContractImplementor session) throws HibernateException {
    final SessionFactoryImplementor factory = session.getFactory();
    UniqueKeyLoadable persister = (UniqueKeyLoadable) factory.getMetamodel().entityPersister(entityName);
    //TODO: implement caching?! proxies?!
    EntityUniqueKey euk = new EntityUniqueKey(entityName, uniqueKeyPropertyName, key, getIdentifierOrUniqueKeyType(factory), persister.getEntityMode(), session.getFactory());
    final PersistenceContext persistenceContext = session.getPersistenceContext();
    Object result = persistenceContext.getEntity(euk);
    if (result == null) {
        result = persister.loadByUniqueKey(uniqueKeyPropertyName, key, session);
    }
    return result == null ? null : persistenceContext.proxyFor(result);
}
Also used : EntityUniqueKey(org.hibernate.engine.spi.EntityUniqueKey) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) PersistenceContext(org.hibernate.engine.spi.PersistenceContext) UniqueKeyLoadable(org.hibernate.persister.entity.UniqueKeyLoadable)

Example 4 with EntityUniqueKey

use of org.hibernate.engine.spi.EntityUniqueKey in project hibernate-orm by hibernate.

the class StatefulPersistenceContext method serialize.

/**
	 * Used by the owning session to explicitly control serialization of the
	 * persistence context.
	 *
	 * @param oos The stream to which the persistence context should get written
	 * @throws IOException serialization errors.
	 */
public void serialize(ObjectOutputStream oos) throws IOException {
    final boolean tracing = LOG.isTraceEnabled();
    if (tracing) {
        LOG.trace("Serializing persisatence-context");
    }
    oos.writeBoolean(defaultReadOnly);
    oos.writeBoolean(hasNonReadOnlyEntities);
    oos.writeInt(entitiesByKey.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + entitiesByKey.size() + "] entitiesByKey entries");
    }
    for (Map.Entry<EntityKey, Object> entry : entitiesByKey.entrySet()) {
        entry.getKey().serialize(oos);
        oos.writeObject(entry.getValue());
    }
    oos.writeInt(entitiesByUniqueKey.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + entitiesByUniqueKey.size() + "] entitiesByUniqueKey entries");
    }
    for (Map.Entry<EntityUniqueKey, Object> entry : entitiesByUniqueKey.entrySet()) {
        entry.getKey().serialize(oos);
        oos.writeObject(entry.getValue());
    }
    oos.writeInt(proxiesByKey.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + proxiesByKey.size() + "] proxiesByKey entries");
    }
    for (Map.Entry<EntityKey, Object> entry : proxiesByKey.entrySet()) {
        entry.getKey().serialize(oos);
        oos.writeObject(entry.getValue());
    }
    oos.writeInt(entitySnapshotsByKey.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + entitySnapshotsByKey.size() + "] entitySnapshotsByKey entries");
    }
    for (Map.Entry<EntityKey, Object> entry : entitySnapshotsByKey.entrySet()) {
        entry.getKey().serialize(oos);
        oos.writeObject(entry.getValue());
    }
    entityEntryContext.serialize(oos);
    oos.writeInt(collectionsByKey.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + collectionsByKey.size() + "] collectionsByKey entries");
    }
    for (Map.Entry<CollectionKey, PersistentCollection> entry : collectionsByKey.entrySet()) {
        entry.getKey().serialize(oos);
        oos.writeObject(entry.getValue());
    }
    oos.writeInt(collectionEntries.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + collectionEntries.size() + "] collectionEntries entries");
    }
    for (Map.Entry<PersistentCollection, CollectionEntry> entry : collectionEntries.entrySet()) {
        oos.writeObject(entry.getKey());
        entry.getValue().serialize(oos);
    }
    oos.writeInt(arrayHolders.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + arrayHolders.size() + "] arrayHolders entries");
    }
    for (Map.Entry<Object, PersistentCollection> entry : arrayHolders.entrySet()) {
        oos.writeObject(entry.getKey());
        oos.writeObject(entry.getValue());
    }
    oos.writeInt(nullifiableEntityKeys.size());
    if (tracing) {
        LOG.trace("Starting serialization of [" + nullifiableEntityKeys.size() + "] nullifiableEntityKey entries");
    }
    for (EntityKey entry : nullifiableEntityKeys) {
        entry.serialize(oos);
    }
}
Also used : CollectionEntry(org.hibernate.engine.spi.CollectionEntry) CollectionKey(org.hibernate.engine.spi.CollectionKey) EntityKey(org.hibernate.engine.spi.EntityKey) PersistentCollection(org.hibernate.collection.spi.PersistentCollection) EntityUniqueKey(org.hibernate.engine.spi.EntityUniqueKey) ConcurrentReferenceHashMap(org.hibernate.internal.util.collections.ConcurrentReferenceHashMap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) IdentityMap(org.hibernate.internal.util.collections.IdentityMap)

Example 5 with EntityUniqueKey

use of org.hibernate.engine.spi.EntityUniqueKey in project hibernate-orm by hibernate.

the class StatefulPersistenceContext method getCollectionOwner.

@Override
public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException {
    // todo : we really just need to add a split in the notions of:
    //		1) collection key
    //		2) collection owner key
    // these 2 are not always the same.  Same is true in the case of ToOne associations with property-ref...
    final EntityPersister ownerPersister = collectionPersister.getOwnerEntityPersister();
    if (ownerPersister.getIdentifierType().getReturnedClass().isInstance(key)) {
        return getEntity(session.generateEntityKey(key, collectionPersister.getOwnerEntityPersister()));
    }
    //		1) The incoming key could be the entity itself...
    if (ownerPersister.isInstance(key)) {
        final Serializable owenerId = ownerPersister.getIdentifier(key, session);
        if (owenerId == null) {
            return null;
        }
        return getEntity(session.generateEntityKey(owenerId, ownerPersister));
    }
    final CollectionType collectionType = collectionPersister.getCollectionType();
    //			a) try by EntityUniqueKey
    if (collectionType.getLHSPropertyName() != null) {
        final Object owner = getEntity(new EntityUniqueKey(ownerPersister.getEntityName(), collectionType.getLHSPropertyName(), key, collectionPersister.getKeyType(), ownerPersister.getEntityMode(), session.getFactory()));
        if (owner != null) {
            return owner;
        }
        //		b) try by EntityKey, which means we need to resolve owner-key -> collection-key
        //			IMPL NOTE : yes if we get here this impl is very non-performant, but PersistenceContext
        //					was never designed to handle this case; adding that capability for real means splitting
        //					the notions of:
        //						1) collection key
        //						2) collection owner key
        // 					these 2 are not always the same (same is true in the case of ToOne associations with
        // 					property-ref).  That would require changes to (at least) CollectionEntry and quite
        //					probably changes to how the sql for collection initializers are generated
        //
        //			We could also possibly see if the referenced property is a natural id since we already have caching
        //			in place of natural id snapshots.  BUt really its better to just do it the right way ^^ if we start
        // 			going that route
        final Serializable ownerId = ownerPersister.getIdByUniqueKey(key, collectionType.getLHSPropertyName(), session);
        return getEntity(session.generateEntityKey(ownerId, ownerPersister));
    }
    // as a last resort this is what the old code did...
    return getEntity(session.generateEntityKey(key, collectionPersister.getOwnerEntityPersister()));
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) Serializable(java.io.Serializable) EntityUniqueKey(org.hibernate.engine.spi.EntityUniqueKey) CollectionType(org.hibernate.type.CollectionType)

Aggregations

EntityUniqueKey (org.hibernate.engine.spi.EntityUniqueKey)5 Serializable (java.io.Serializable)3 UniqueKeyLoadable (org.hibernate.persister.entity.UniqueKeyLoadable)3 EntityPersister (org.hibernate.persister.entity.EntityPersister)2 Loadable (org.hibernate.persister.entity.Loadable)2 EntityType (org.hibernate.type.EntityType)2 Type (org.hibernate.type.Type)2 VersionType (org.hibernate.type.VersionType)2 SQLException (java.sql.SQLException)1 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1 Map (java.util.Map)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 PersistentCollection (org.hibernate.collection.spi.PersistentCollection)1 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)1 CollectionEntry (org.hibernate.engine.spi.CollectionEntry)1 CollectionKey (org.hibernate.engine.spi.CollectionKey)1 EntityKey (org.hibernate.engine.spi.EntityKey)1 PersistenceContext (org.hibernate.engine.spi.PersistenceContext)1 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)1