use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultSaveOrUpdateEventListener method performUpdate.
protected void performUpdate(SaveOrUpdateEvent event, Object entity, EntityPersister persister) throws HibernateException {
final boolean traceEnabled = LOG.isTraceEnabled();
if (traceEnabled && !persister.isMutable()) {
LOG.trace("Immutable instance passed to performUpdate()");
}
if (traceEnabled) {
LOG.tracev("Updating {0}", MessageHelper.infoString(persister, event.getRequestedId(), event.getSession().getFactory()));
}
final EventSource source = event.getSession();
final EntityKey key = source.generateEntityKey(event.getRequestedId(), persister);
source.getPersistenceContext().checkUniqueness(key, entity);
if (invokeUpdateLifecycle(entity, persister, source)) {
reassociate(event, event.getObject(), event.getRequestedId(), persister);
return;
}
// this is a transient object with existing persistent state not loaded by the session
new OnUpdateVisitor(source, event.getRequestedId(), entity).process(entity, persister);
// TODO: put this stuff back in to read snapshot from
// the second-level cache (needs some extra work)
/*Object[] cachedState = null;
if ( persister.hasCache() ) {
CacheEntry entry = (CacheEntry) persister.getCache()
.get( event.getRequestedId(), source.getTimestamp() );
cachedState = entry==null ?
null :
entry.getState(); //TODO: half-assemble this stuff
}*/
source.getPersistenceContext().addEntity(entity, (persister.isMutable() ? Status.MANAGED : Status.READ_ONLY), // cachedState,
null, key, persister.getVersion(entity), LockMode.NONE, true, persister, false);
persister.afterReassociate(entity, source);
if (traceEnabled) {
LOG.tracev("Updating {0}", MessageHelper.infoString(persister, event.getRequestedId(), source.getFactory()));
}
cascadeOnUpdate(event, persister, entity);
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class Loader method loadSequentialRowsReverse.
/**
* Loads a single logical row from the result set moving forward. This is the
* processing used from the ScrollableResults where there were collection fetches
* encountered; thus a single logical row may have multiple rows in the underlying
* result set.
*
* @param resultSet The result set from which to do the load.
* @param session The session from which the request originated.
* @param queryParameters The query parameters specified by the user.
* @param returnProxies Should proxies be generated
*
* @return The loaded "row".
*
* @throws HibernateException
*/
public Object loadSequentialRowsReverse(final ResultSet resultSet, final SharedSessionContractImplementor session, final QueryParameters queryParameters, final boolean returnProxies, final boolean isLogicallyAfterLast) throws HibernateException {
try {
if (resultSet.isFirst()) {
// don't even bother trying to read any further
return null;
}
EntityKey keyToRead = null;
// previous logical row).
if (resultSet.isAfterLast() && isLogicallyAfterLast) {
// position cursor to the last row
resultSet.last();
keyToRead = getKeyFromResultSet(0, getEntityPersisters()[0], null, resultSet, session);
} else {
// Since the result set cursor is always left at the first
// physical row afterQuery the "last processed", we need to jump
// back one position to get the key value we are interested
// in skipping
resultSet.previous();
// sequentially read the result set in reverse until we recognize
// a change in the key value. At that point, we are pointed at
// the last physical sequential row for the logical row in which
// we are interested in processing
boolean firstPass = true;
final EntityKey lastKey = getKeyFromResultSet(0, getEntityPersisters()[0], null, resultSet, session);
while (resultSet.previous()) {
EntityKey checkKey = getKeyFromResultSet(0, getEntityPersisters()[0], null, resultSet, session);
if (firstPass) {
firstPass = false;
keyToRead = checkKey;
}
if (!lastKey.equals(checkKey)) {
break;
}
}
}
// row with the key we are interested in loading
while (resultSet.previous()) {
EntityKey checkKey = getKeyFromResultSet(0, getEntityPersisters()[0], null, resultSet, session);
if (!keyToRead.equals(checkKey)) {
break;
}
}
// Finally, read ahead one row to position result set cursor
// at the first physical row we are interested in loading
resultSet.next();
// and doAfterTransactionCompletion the load
return sequentialLoad(resultSet, session, queryParameters, returnProxies, keyToRead);
} catch (SQLException sqle) {
throw factory.getJdbcServices().getSqlExceptionHelper().convert(sqle, "could not doAfterTransactionCompletion sequential read of results (forward)", getSQLString());
}
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class Loader method getRow.
/**
* Resolve any IDs for currently loaded objects, duplications within the
* <tt>ResultSet</tt>, etc. Instantiate empty objects to be initialized from the
* <tt>ResultSet</tt>. Return an array of objects (a row of results) and an
* array of booleans (by side-effect) that determine whether the corresponding
* object should be initialized.
*/
private Object[] getRow(final ResultSet rs, final Loadable[] persisters, final EntityKey[] keys, final Object optionalObject, final EntityKey optionalObjectKey, final LockMode[] lockModes, final List hydratedObjects, final SharedSessionContractImplementor session) throws HibernateException, SQLException {
final int cols = persisters.length;
final EntityAliases[] descriptors = getEntityAliases();
if (LOG.isDebugEnabled()) {
LOG.debugf("Result row: %s", StringHelper.toString(keys));
}
final Object[] rowResults = new Object[cols];
for (int i = 0; i < cols; i++) {
Object object = null;
EntityKey key = keys[i];
if (keys[i] == null) {
//do nothing
} else {
//If the object is already loaded, return the loaded one
object = session.getEntityUsingInterceptor(key);
if (object != null) {
//its already loaded so don't need to hydrate it
instanceAlreadyLoaded(rs, i, persisters[i], key, object, lockModes[i], session);
} else {
object = instanceNotYetLoaded(rs, i, persisters[i], descriptors[i].getRowIdAlias(), key, lockModes[i], optionalObjectKey, optionalObject, hydratedObjects, session);
}
}
rowResults[i] = object;
}
return rowResults;
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class Loader method createSubselects.
private void createSubselects(List keys, QueryParameters queryParameters, SharedSessionContractImplementor session) {
if (keys.size() > 1) {
//if we only returned one entity, query by key is more efficient
Set[] keySets = transpose(keys);
Map namedParameterLocMap = buildNamedParameterLocMap(queryParameters);
final Loadable[] loadables = getEntityPersisters();
final String[] aliases = getAliases();
final String subselectQueryString = SubselectFetch.createSubselectFetchQueryFragment(queryParameters);
for (Object key : keys) {
final EntityKey[] rowKeys = (EntityKey[]) key;
for (int i = 0; i < rowKeys.length; i++) {
if (rowKeys[i] != null && loadables[i].hasSubselectLoadableCollections()) {
SubselectFetch subselectFetch = new SubselectFetch(subselectQueryString, aliases[i], loadables[i], queryParameters, keySets[i], namedParameterLocMap);
session.getPersistenceContext().getBatchFetchQueue().addSubselect(rowKeys[i], subselectFetch);
}
}
}
}
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class Loader method sequentialLoad.
private Object sequentialLoad(final ResultSet resultSet, final SharedSessionContractImplementor session, final QueryParameters queryParameters, final boolean returnProxies, final EntityKey keyToRead) throws HibernateException {
final int entitySpan = getEntityPersisters().length;
final List hydratedObjects = entitySpan == 0 ? null : new ArrayList(entitySpan);
Object result = null;
final EntityKey[] loadedKeys = new EntityKey[entitySpan];
try {
do {
Object loaded = getRowFromResultSet(resultSet, session, queryParameters, getLockModes(queryParameters.getLockOptions()), null, hydratedObjects, loadedKeys, returnProxies);
if (!keyToRead.equals(loadedKeys[0])) {
throw new AssertionFailure(String.format("Unexpected key read for row; expected [%s]; actual [%s]", keyToRead, loadedKeys[0]));
}
if (result == null) {
result = loaded;
}
} while (resultSet.next() && isCurrentRowForSameEntity(keyToRead, 0, resultSet, session));
} catch (SQLException sqle) {
throw factory.getJdbcServices().getSqlExceptionHelper().convert(sqle, "could not doAfterTransactionCompletion sequential read of results (forward)", getSQLString());
}
initializeEntitiesAndCollections(hydratedObjects, resultSet, session, queryParameters.isReadOnly(session));
session.getPersistenceContext().initializeNonLazyCollections();
return result;
}
Aggregations