use of org.hibernate.loader.spi.AfterLoadAction in project hibernate-orm by hibernate.
the class Loader method shouldUseFollowOnLocking.
protected boolean shouldUseFollowOnLocking(QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) {
if ((parameters.getLockOptions().getFollowOnLocking() == null && dialect.useFollowOnLocking(parameters)) || (parameters.getLockOptions().getFollowOnLocking() != null && parameters.getLockOptions().getFollowOnLocking())) {
// currently only one lock mode is allowed in follow-on locking
final LockMode lockMode = determineFollowOnLockMode(parameters.getLockOptions());
final LockOptions lockOptions = new LockOptions(lockMode);
if (lockOptions.getLockMode() != LockMode.UPGRADE_SKIPLOCKED) {
if (lockOptions.getLockMode() != LockMode.NONE) {
LOG.usingFollowOnLocking();
}
lockOptions.setTimeOut(parameters.getLockOptions().getTimeOut());
lockOptions.setScope(parameters.getLockOptions().getScope());
afterLoadActions.add(new AfterLoadAction() {
@Override
public void afterLoad(SharedSessionContractImplementor session, Object entity, Loadable persister) {
((Session) session).buildLockRequest(lockOptions).lock(persister.getEntityName(), entity);
}
});
parameters.setLockOptions(new LockOptions());
return true;
}
}
return false;
}
use of org.hibernate.loader.spi.AfterLoadAction in project hibernate-orm by hibernate.
the class Loader method scroll.
/**
* Return the query results, as an instance of <tt>ScrollableResults</tt>
*
* @param queryParameters The parameters with which the query should be executed.
* @param returnTypes The expected return types of the query
* @param holderInstantiator If the return values are expected to be wrapped
* in a holder, this is the thing that knows how to wrap them.
* @param session The session from which the scroll request originated.
*
* @return The ScrollableResults instance.
*
* @throws HibernateException Indicates an error executing the query, or constructing
* the ScrollableResults.
*/
protected ScrollableResultsImplementor scroll(final QueryParameters queryParameters, final Type[] returnTypes, final HolderInstantiator holderInstantiator, final SharedSessionContractImplementor session) throws HibernateException {
checkScrollability();
final boolean stats = getQueryIdentifier() != null && getFactory().getStatistics().isStatisticsEnabled();
long startTime = 0;
if (stats) {
startTime = System.nanoTime();
}
try {
// Don't use Collections#emptyList() here -- follow on locking potentially adds AfterLoadActions,
// so the list cannot be immutable.
final SqlStatementWrapper wrapper = executeQueryStatement(queryParameters, true, new ArrayList<AfterLoadAction>(), session);
final ResultSet rs = wrapper.getResultSet();
final PreparedStatement st = (PreparedStatement) wrapper.getStatement();
if (stats) {
final long endTime = System.nanoTime();
final long milliseconds = TimeUnit.MILLISECONDS.convert(endTime - startTime, TimeUnit.NANOSECONDS);
getFactory().getStatistics().queryExecuted(getQueryIdentifier(), 0, milliseconds);
}
if (needsFetchingScroll()) {
return new FetchingScrollableResultsImpl(rs, st, session, this, queryParameters, returnTypes, holderInstantiator);
} else {
return new ScrollableResultsImpl(rs, st, session, this, queryParameters, returnTypes, holderInstantiator);
}
} catch (SQLException sqle) {
throw factory.getJdbcServices().getSqlExceptionHelper().convert(sqle, "could not execute query using scroll", getSQLString());
}
}
use of org.hibernate.loader.spi.AfterLoadAction in project hibernate-orm by hibernate.
the class Loader method initializeEntitiesAndCollections.
private void initializeEntitiesAndCollections(final List hydratedObjects, final Object resultSetId, final SharedSessionContractImplementor session, final boolean readOnly, List<AfterLoadAction> afterLoadActions) throws HibernateException {
final CollectionPersister[] collectionPersisters = getCollectionPersisters();
if (collectionPersisters != null) {
for (CollectionPersister collectionPersister : collectionPersisters) {
if (collectionPersister.isArray()) {
//for arrays, we should end the collection load beforeQuery resolving
//the entities, since the actual array instances are not instantiated
//during loading
//TODO: or we could do this polymorphically, and have two
// different operations implemented differently for arrays
endCollectionLoad(resultSetId, session, collectionPersister);
}
}
}
//important: reuse the same event instances for performance!
final PreLoadEvent pre;
final PostLoadEvent post;
if (session.isEventSource()) {
pre = new PreLoadEvent((EventSource) session);
post = new PostLoadEvent((EventSource) session);
} else {
pre = null;
post = null;
}
if (hydratedObjects != null) {
int hydratedObjectsSize = hydratedObjects.size();
LOG.tracev("Total objects hydrated: {0}", hydratedObjectsSize);
for (Object hydratedObject : hydratedObjects) {
TwoPhaseLoad.initializeEntity(hydratedObject, readOnly, session, pre);
}
}
if (collectionPersisters != null) {
for (CollectionPersister collectionPersister : collectionPersisters) {
if (!collectionPersister.isArray()) {
//for sets, we should end the collection load afterQuery resolving
//the entities, since we might call hashCode() on the elements
//TODO: or we could do this polymorphically, and have two
// different operations implemented differently for arrays
endCollectionLoad(resultSetId, session, collectionPersister);
}
}
}
// persistence context.
if (hydratedObjects != null) {
for (Object hydratedObject : hydratedObjects) {
TwoPhaseLoad.postLoad(hydratedObject, session, post);
if (afterLoadActions != null) {
for (AfterLoadAction afterLoadAction : afterLoadActions) {
final EntityEntry entityEntry = session.getPersistenceContext().getEntry(hydratedObject);
if (entityEntry == null) {
// big problem
throw new HibernateException("Could not locate EntityEntry immediately afterQuery two-phase load");
}
afterLoadAction.afterLoad(session, hydratedObject, (Loadable) entityEntry.getPersister());
}
}
}
}
}
use of org.hibernate.loader.spi.AfterLoadAction in project hibernate-orm by hibernate.
the class Loader method doQuery.
private List doQuery(final SharedSessionContractImplementor session, final QueryParameters queryParameters, final boolean returnProxies, final ResultTransformer forcedResultTransformer) throws SQLException, HibernateException {
final RowSelection selection = queryParameters.getRowSelection();
final int maxRows = LimitHelper.hasMaxRows(selection) ? selection.getMaxRows() : Integer.MAX_VALUE;
final List<AfterLoadAction> afterLoadActions = new ArrayList<AfterLoadAction>();
final SqlStatementWrapper wrapper = executeQueryStatement(queryParameters, false, afterLoadActions, session);
final ResultSet rs = wrapper.getResultSet();
final Statement st = wrapper.getStatement();
try {
return processResultSet(rs, queryParameters, session, returnProxies, forcedResultTransformer, maxRows, afterLoadActions);
} finally {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(st);
session.getJdbcCoordinator().afterStatementExecution();
}
}
use of org.hibernate.loader.spi.AfterLoadAction in project hibernate-orm by hibernate.
the class CriteriaLoader method applyLocks.
@Override
protected String applyLocks(String sql, QueryParameters parameters, Dialect dialect, List<AfterLoadAction> afterLoadActions) throws QueryException {
final LockOptions lockOptions = parameters.getLockOptions();
if (lockOptions == null || (lockOptions.getLockMode() == LockMode.NONE && (lockOptions.getAliasLockCount() == 0 || (lockOptions.getAliasLockCount() == 1 && lockOptions.getAliasSpecificLockMode("this_") == LockMode.NONE)))) {
return sql;
}
if ((parameters.getLockOptions().getFollowOnLocking() == null && dialect.useFollowOnLocking(parameters)) || (parameters.getLockOptions().getFollowOnLocking() != null && parameters.getLockOptions().getFollowOnLocking())) {
final LockMode lockMode = determineFollowOnLockMode(lockOptions);
if (lockMode != LockMode.UPGRADE_SKIPLOCKED) {
// Dialect prefers to perform locking in a separate step
LOG.usingFollowOnLocking();
final LockOptions lockOptionsToUse = new LockOptions(lockMode);
lockOptionsToUse.setTimeOut(lockOptions.getTimeOut());
lockOptionsToUse.setScope(lockOptions.getScope());
afterLoadActions.add(new AfterLoadAction() {
@Override
public void afterLoad(SharedSessionContractImplementor session, Object entity, Loadable persister) {
((Session) session).buildLockRequest(lockOptionsToUse).lock(persister.getEntityName(), entity);
}
});
parameters.setLockOptions(new LockOptions());
return sql;
}
}
final LockOptions locks = new LockOptions(lockOptions.getLockMode());
locks.setScope(lockOptions.getScope());
locks.setTimeOut(lockOptions.getTimeOut());
final Map<String, String[]> keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
final String[] drivingSqlAliases = getAliases();
for (int i = 0; i < drivingSqlAliases.length; i++) {
final LockMode lockMode = lockOptions.getAliasSpecificLockMode(drivingSqlAliases[i]);
if (lockMode != null) {
final Lockable drivingPersister = (Lockable) getEntityPersisters()[i];
final String rootSqlAlias = drivingPersister.getRootTableAlias(drivingSqlAliases[i]);
locks.setAliasSpecificLockMode(rootSqlAlias, lockMode);
if (keyColumnNames != null) {
keyColumnNames.put(rootSqlAlias, drivingPersister.getRootTableIdentifierColumnNames());
}
}
}
return dialect.applyLocksToSql(sql, locks, keyColumnNames);
}
Aggregations