HHH-4545 - Allow o.h.action.Executable to register for either (or both) before or after transaction completion callbacks
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17913 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
ecaf3990b8
commit
9c74610a9d
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.action;
|
||||
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
|
||||
/**
|
||||
* Contract representing some process that needs to occur during after transaction completion.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface AfterTransactionCompletionProcess {
|
||||
/**
|
||||
* Perform whatever processing is encapsulated here after completion of the transaction.
|
||||
*
|
||||
* @param success Did the transaction complete successfully? True means it did.
|
||||
* @param session The session on which the transaction is completing.
|
||||
*/
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.action;
|
||||
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
|
||||
/**
|
||||
* Contract representing some process that needs to occur during before transaction completion.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface BeforeTransactionCompletionProcess {
|
||||
/**
|
||||
* Perform whatever processing is encapsulated here before completion of the transaction.
|
||||
*
|
||||
* @param session The session on which the transaction is preparing to complete.
|
||||
*/
|
||||
public void doBeforeTransactionCompletion(SessionImplementor session);
|
||||
}
|
|
@ -70,19 +70,13 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
* @param session The session to which this request is tied.
|
||||
* @param affectedQueryables The affected entity persisters.
|
||||
*/
|
||||
public BulkOperationCleanupAction(
|
||||
SessionImplementor session,
|
||||
Queryable[] affectedQueryables) {
|
||||
public BulkOperationCleanupAction(SessionImplementor session, Queryable[] affectedQueryables) {
|
||||
SessionFactoryImplementor factory = session.getFactory();
|
||||
ArrayList tmpSpaces = new ArrayList();
|
||||
for ( int i = 0; i < affectedQueryables.length; i++ ) {
|
||||
tmpSpaces.addAll( Arrays.asList( affectedQueryables[i].getQuerySpaces() ) );
|
||||
if ( affectedQueryables[i].hasCache() ) {
|
||||
entityCleanups.add(
|
||||
new EntityCleanup(
|
||||
affectedQueryables[i].getCacheAccessStrategy()
|
||||
)
|
||||
);
|
||||
entityCleanups.add( new EntityCleanup( affectedQueryables[i].getCacheAccessStrategy() ) );
|
||||
}
|
||||
Set roles = factory.getCollectionRolesByEntityParticipant( affectedQueryables[i].getEntityName() );
|
||||
if ( roles != null ) {
|
||||
|
@ -91,11 +85,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
String role = ( String ) itr.next();
|
||||
CollectionPersister collectionPersister = factory.getCollectionPersister( role );
|
||||
if ( collectionPersister.hasCache() ) {
|
||||
collectionCleanups.add(
|
||||
new CollectionCleanup(
|
||||
collectionPersister.getCacheAccessStrategy()
|
||||
)
|
||||
);
|
||||
collectionCleanups.add( new CollectionCleanup( collectionPersister.getCacheAccessStrategy() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +119,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
if ( affectedEntity( tableSpaces, entitySpaces ) ) {
|
||||
tmpSpaces.addAll( Arrays.asList( entitySpaces ) );
|
||||
if ( persister.hasCache() ) {
|
||||
entityCleanups.add(
|
||||
new EntityCleanup(
|
||||
persister.getCacheAccessStrategy()
|
||||
)
|
||||
);
|
||||
entityCleanups.add( new EntityCleanup( persister.getCacheAccessStrategy() ) );
|
||||
}
|
||||
Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() );
|
||||
if ( roles != null ) {
|
||||
|
@ -143,9 +129,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
CollectionPersister collectionPersister = factory.getCollectionPersister( role );
|
||||
if ( collectionPersister.hasCache() ) {
|
||||
collectionCleanups.add(
|
||||
new CollectionCleanup(
|
||||
collectionPersister.getCacheAccessStrategy()
|
||||
)
|
||||
new CollectionCleanup( collectionPersister.getCacheAccessStrategy() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -169,9 +153,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
* @return True if there are affected table spaces and any of the incoming
|
||||
* check table spaces occur in that set.
|
||||
*/
|
||||
private boolean affectedEntity(
|
||||
Set affectedTableSpaces,
|
||||
Serializable[] checkTableSpaces) {
|
||||
private boolean affectedEntity(Set affectedTableSpaces, Serializable[] checkTableSpaces) {
|
||||
if ( affectedTableSpaces == null || affectedTableSpaces.isEmpty() ) {
|
||||
return true;
|
||||
}
|
||||
|
@ -188,22 +170,26 @@ public class BulkOperationCleanupAction implements Executable, Serializable {
|
|||
return affectedTableSpaces;
|
||||
}
|
||||
|
||||
public boolean hasAfterTransactionCompletion() {
|
||||
return true;
|
||||
public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void afterTransactionCompletion(boolean success) throws HibernateException {
|
||||
Iterator itr = entityCleanups.iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final EntityCleanup cleanup = ( EntityCleanup ) itr.next();
|
||||
cleanup.release();
|
||||
}
|
||||
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() {
|
||||
return new AfterTransactionCompletionProcess() {
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
|
||||
Iterator itr = entityCleanups.iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final EntityCleanup cleanup = ( EntityCleanup ) itr.next();
|
||||
cleanup.release();
|
||||
}
|
||||
|
||||
itr = collectionCleanups.iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final CollectionCleanup cleanup = ( CollectionCleanup ) itr.next();
|
||||
cleanup.release();
|
||||
}
|
||||
itr = collectionCleanups.iterator();
|
||||
while ( itr.hasNext() ) {
|
||||
final CollectionCleanup cleanup = ( CollectionCleanup ) itr.next();
|
||||
cleanup.release();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void beforeExecutions() throws HibernateException {
|
||||
|
|
|
@ -39,15 +39,13 @@ import java.io.Serializable;
|
|||
|
||||
/**
|
||||
* Any action relating to insert/update/delete of a collection
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public abstract class CollectionAction implements Executable, Serializable, Comparable {
|
||||
|
||||
private transient CollectionPersister persister;
|
||||
private final Serializable key;
|
||||
private Serializable finalKey;
|
||||
private final SessionImplementor session;
|
||||
private SoftLock lock;
|
||||
private final String collectionRole;
|
||||
private final PersistentCollection collection;
|
||||
|
||||
|
@ -62,31 +60,45 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
|
|||
this.collectionRole = persister.getRole();
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
|
||||
protected PersistentCollection getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
protected void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
persister = session.getFactory().getCollectionPersister( collectionRole );
|
||||
}
|
||||
|
||||
public void afterTransactionCompletion(boolean success) throws CacheException {
|
||||
public final void beforeExecutions() throws CacheException {
|
||||
// we need to obtain the lock before any actions are
|
||||
// executed, since this may be an inverse="true"
|
||||
// bidirectional association and it is one of the
|
||||
// earlier entity actions which actually updates
|
||||
// the database (this action is resposible for
|
||||
// second-level cache invalidation only)
|
||||
if ( persister.hasCache() ) {
|
||||
final CacheKey ck = new CacheKey(
|
||||
key,
|
||||
persister.getKeyType(),
|
||||
persister.getRole(),
|
||||
session.getEntityMode(),
|
||||
session.getFactory()
|
||||
);
|
||||
persister.getCacheAccessStrategy().unlockItem( ck, lock );
|
||||
final CacheKey ck = new CacheKey(
|
||||
key,
|
||||
persister.getKeyType(),
|
||||
persister.getRole(),
|
||||
session.getEntityMode(),
|
||||
session.getFactory()
|
||||
);
|
||||
final SoftLock lock = persister.getCacheAccessStrategy().lockItem( ck, null );
|
||||
// the old behavior used key as opposed to getKey()
|
||||
afterTransactionProcess = new CacheCleanupProcess( key, persister, lock );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAfterTransactionCompletion() {
|
||||
return persister.hasCache();
|
||||
public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private AfterTransactionCompletionProcess afterTransactionProcess;
|
||||
|
||||
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() {
|
||||
return afterTransactionProcess;
|
||||
}
|
||||
|
||||
public Serializable[] getPropertySpaces() {
|
||||
|
@ -98,7 +110,7 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
|
|||
}
|
||||
|
||||
protected final Serializable getKey() {
|
||||
finalKey = key;
|
||||
Serializable finalKey = key;
|
||||
if ( key instanceof DelayedPostInsertIdentifier ) {
|
||||
// need to look it up from the persistence-context
|
||||
finalKey = session.getPersistenceContext().getEntry( collection.getOwner() ).getId();
|
||||
|
@ -114,25 +126,6 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
|
|||
return session;
|
||||
}
|
||||
|
||||
public final void beforeExecutions() throws CacheException {
|
||||
// we need to obtain the lock before any actions are
|
||||
// executed, since this may be an inverse="true"
|
||||
// bidirectional association and it is one of the
|
||||
// earlier entity actions which actually updates
|
||||
// the database (this action is resposible for
|
||||
// second-level cache invalidation only)
|
||||
if ( persister.hasCache() ) {
|
||||
final CacheKey ck = new CacheKey(
|
||||
key,
|
||||
persister.getKeyType(),
|
||||
persister.getRole(),
|
||||
session.getEntityMode(),
|
||||
session.getFactory()
|
||||
);
|
||||
lock = persister.getCacheAccessStrategy().lockItem( ck, null );
|
||||
}
|
||||
}
|
||||
|
||||
protected final void evict() throws CacheException {
|
||||
if ( persister.hasCache() ) {
|
||||
CacheKey ck = new CacheKey(
|
||||
|
@ -164,6 +157,29 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
|
|||
.compare( key, action.key, session.getEntityMode() );
|
||||
}
|
||||
}
|
||||
|
||||
private static class CacheCleanupProcess implements AfterTransactionCompletionProcess {
|
||||
private final Serializable key;
|
||||
private final CollectionPersister persister;
|
||||
private final SoftLock lock;
|
||||
|
||||
private CacheCleanupProcess(Serializable key, CollectionPersister persister, SoftLock lock) {
|
||||
this.key = key;
|
||||
this.persister = persister;
|
||||
this.lock = lock;
|
||||
}
|
||||
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
|
||||
final CacheKey ck = new CacheKey(
|
||||
key,
|
||||
persister.getKeyType(),
|
||||
persister.getRole(),
|
||||
session.getEntityMode(),
|
||||
session.getFactory()
|
||||
);
|
||||
persister.getCacheAccessStrategy().unlockItem( ck, lock );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ import java.io.Serializable;
|
|||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public abstract class EntityAction implements Executable, Serializable, Comparable {
|
||||
public abstract class EntityAction
|
||||
implements Executable, Serializable, Comparable, AfterTransactionCompletionProcess {
|
||||
|
||||
private final String entityName;
|
||||
private final Serializable id;
|
||||
|
@ -65,8 +66,22 @@ public abstract class EntityAction implements Executable, Serializable, Comparab
|
|||
this.persister = persister;
|
||||
}
|
||||
|
||||
public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() {
|
||||
return needsAfterTransactionCompletion()
|
||||
? this
|
||||
: null;
|
||||
}
|
||||
|
||||
protected abstract boolean hasPostCommitEventListeners();
|
||||
|
||||
public boolean needsAfterTransactionCompletion() {
|
||||
return persister.hasCache() || hasPostCommitEventListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* entity name accessor
|
||||
*
|
||||
|
@ -123,10 +138,6 @@ public abstract class EntityAction implements Executable, Serializable, Comparab
|
|||
throw new AssertionFailure( "beforeExecutions() called for non-collection action" );
|
||||
}
|
||||
|
||||
public boolean hasAfterTransactionCompletion() {
|
||||
return persister.hasCache() || hasPostCommitEventListeners();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return StringHelper.unqualify( getClass().getName() ) + MessageHelper.infoString( entityName, id );
|
||||
}
|
||||
|
|
|
@ -42,12 +42,12 @@ import org.hibernate.event.EventSource;
|
|||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
public final class EntityDeleteAction extends EntityAction {
|
||||
|
||||
private final Object version;
|
||||
private SoftLock lock;
|
||||
private final boolean isCascadeDeleteEnabled;
|
||||
private final Object[] state;
|
||||
|
||||
private SoftLock lock;
|
||||
|
||||
public EntityDeleteAction(
|
||||
final Serializable id,
|
||||
final Object[] state,
|
||||
|
@ -86,7 +86,7 @@ public final class EntityDeleteAction extends EntityAction {
|
|||
persister.getRootEntityName(),
|
||||
session.getEntityMode(),
|
||||
session.getFactory()
|
||||
);
|
||||
);
|
||||
lock = persister.getCacheAccessStrategy().lockItem( ck, version );
|
||||
}
|
||||
else {
|
||||
|
@ -112,19 +112,19 @@ public final class EntityDeleteAction extends EntityAction {
|
|||
persistenceContext.removeEntity(key);
|
||||
persistenceContext.removeProxy(key);
|
||||
|
||||
if ( persister.hasCache() ) persister.getCacheAccessStrategy().remove( ck );
|
||||
if ( persister.hasCache() ) {
|
||||
persister.getCacheAccessStrategy().remove( ck );
|
||||
}
|
||||
|
||||
postDelete();
|
||||
|
||||
if ( getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
|
||||
getSession().getFactory().getStatisticsImplementor()
|
||||
.deleteEntity( getPersister().getEntityName() );
|
||||
getSession().getFactory().getStatisticsImplementor().deleteEntity( getPersister().getEntityName() );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean preDelete() {
|
||||
PreDeleteEventListener[] preListeners = getSession().getListeners()
|
||||
.getPreDeleteEventListeners();
|
||||
PreDeleteEventListener[] preListeners = getSession().getListeners().getPreDeleteEventListeners();
|
||||
boolean veto = false;
|
||||
if (preListeners.length>0) {
|
||||
PreDeleteEvent preEvent = new PreDeleteEvent( getInstance(), getId(), state, getPersister() ,(EventSource) getSession() );
|
||||
|
@ -169,29 +169,21 @@ public final class EntityDeleteAction extends EntityAction {
|
|||
}
|
||||
}
|
||||
|
||||
public void afterTransactionCompletion(boolean success) throws HibernateException {
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException {
|
||||
if ( getPersister().hasCache() ) {
|
||||
final CacheKey ck = new CacheKey(
|
||||
getId(),
|
||||
getPersister().getIdentifierType(),
|
||||
final CacheKey ck = new CacheKey(
|
||||
getId(),
|
||||
getPersister().getIdentifierType(),
|
||||
getPersister().getRootEntityName(),
|
||||
getSession().getEntityMode(),
|
||||
getSession().getEntityMode(),
|
||||
getSession().getFactory()
|
||||
);
|
||||
);
|
||||
getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
|
||||
}
|
||||
postCommitDelete();
|
||||
}
|
||||
|
||||
protected boolean hasPostCommitEventListeners() {
|
||||
return getSession().getListeners().getPostCommitDeleteEventListeners().length>0;
|
||||
return getSession().getListeners().getPostCommitDeleteEventListeners().length > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ import org.hibernate.event.PreInsertEventListener;
|
|||
import org.hibernate.event.EventSource;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
public final class EntityIdentityInsertAction extends EntityAction {
|
||||
public final class EntityIdentityInsertAction extends EntityAction {
|
||||
|
||||
private final Object[] state;
|
||||
private final boolean isDelayed;
|
||||
private final EntityKey delayedEntityKey;
|
||||
|
@ -53,11 +54,10 @@ public final class EntityIdentityInsertAction extends EntityAction {
|
|||
super( session, null, instance, persister );
|
||||
this.state = state;
|
||||
this.isDelayed = isDelayed;
|
||||
delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;
|
||||
this.delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;
|
||||
}
|
||||
|
||||
public void execute() throws HibernateException {
|
||||
|
||||
final EntityPersister persister = getPersister();
|
||||
final SessionImplementor session = getSession();
|
||||
final Object instance = getInstance();
|
||||
|
@ -89,12 +89,29 @@ public final class EntityIdentityInsertAction extends EntityAction {
|
|||
postInsert();
|
||||
|
||||
if ( session.getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
|
||||
session.getFactory().getStatisticsImplementor()
|
||||
.insertEntity( getPersister().getEntityName() );
|
||||
session.getFactory().getStatisticsImplementor().insertEntity( getPersister().getEntityName() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean needsAfterTransactionCompletion() {
|
||||
//TODO: simply remove this override if we fix the above todos
|
||||
return hasPostCommitEventListeners();
|
||||
}
|
||||
|
||||
protected boolean hasPostCommitEventListeners() {
|
||||
return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
|
||||
}
|
||||
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
|
||||
//TODO: reenable if we also fix the above todo
|
||||
/*EntityPersister persister = getEntityPersister();
|
||||
if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
|
||||
persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
|
||||
}*/
|
||||
postCommitInsert();
|
||||
}
|
||||
|
||||
private void postInsert() {
|
||||
if ( isDelayed ) {
|
||||
getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
|
||||
|
@ -145,26 +162,6 @@ public final class EntityIdentityInsertAction extends EntityAction {
|
|||
return veto;
|
||||
}
|
||||
|
||||
//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
|
||||
public void afterTransactionCompletion(boolean success) throws HibernateException {
|
||||
//TODO: reenable if we also fix the above todo
|
||||
/*EntityPersister persister = getEntityPersister();
|
||||
if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
|
||||
persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
|
||||
}*/
|
||||
postCommitInsert();
|
||||
}
|
||||
|
||||
public boolean hasAfterTransactionCompletion() {
|
||||
//TODO: simply remove this override
|
||||
// if we fix the above todos
|
||||
return hasPostCommitEventListeners();
|
||||
}
|
||||
|
||||
protected boolean hasPostCommitEventListeners() {
|
||||
return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
|
||||
}
|
||||
|
||||
public final Serializable getGeneratedId() {
|
||||
return generatedId;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,6 @@ public final class EntityInsertAction extends EntityAction {
|
|||
session.getEntityMode(),
|
||||
session.getFactory()
|
||||
);
|
||||
// boolean put = persister.getCache().insert(ck, cacheEntry);
|
||||
boolean put = persister.getCacheAccessStrategy().insert( ck, cacheEntry, version );
|
||||
|
||||
if ( put && factory.getStatistics().isStatisticsEnabled() ) {
|
||||
|
@ -181,8 +180,10 @@ public final class EntityInsertAction extends EntityAction {
|
|||
return veto;
|
||||
}
|
||||
|
||||
//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
|
||||
public void afterTransactionCompletion(boolean success) throws HibernateException {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws HibernateException {
|
||||
EntityPersister persister = getPersister();
|
||||
if ( success && isCachePutEnabled( persister, getSession() ) ) {
|
||||
final CacheKey ck = new CacheKey(
|
||||
|
@ -191,7 +192,7 @@ public final class EntityInsertAction extends EntityAction {
|
|||
persister.getRootEntityName(),
|
||||
getSession().getEntityMode(),
|
||||
getSession().getFactory()
|
||||
);
|
||||
);
|
||||
boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
|
||||
|
||||
if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
|
||||
|
@ -207,16 +208,9 @@ public final class EntityInsertAction extends EntityAction {
|
|||
}
|
||||
|
||||
private boolean isCachePutEnabled(EntityPersister persister, SessionImplementor session) {
|
||||
return persister.hasCache() &&
|
||||
!persister.isCacheInvalidationRequired() &&
|
||||
session.getCacheMode().isPutEnabled();
|
||||
return persister.hasCache()
|
||||
&& !persister.isCacheInvalidationRequired()
|
||||
&& session.getCacheMode().isPutEnabled();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -46,14 +46,13 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.type.TypeFactory;
|
||||
|
||||
public final class EntityUpdateAction extends EntityAction {
|
||||
|
||||
private final Object[] state;
|
||||
private final Object[] previousState;
|
||||
private final Object previousVersion;
|
||||
private Object nextVersion;
|
||||
private final int[] dirtyFields;
|
||||
private final boolean hasDirtyCollection;
|
||||
private final Object rowId;
|
||||
private Object nextVersion;
|
||||
private Object cacheEntry;
|
||||
private SoftLock lock;
|
||||
|
||||
|
@ -149,7 +148,7 @@ public final class EntityUpdateAction extends EntityAction {
|
|||
nextVersion = Versioning.getVersion( state, persister );
|
||||
}
|
||||
}
|
||||
// have the entity entry perform post-update processing, passing it the
|
||||
// have the entity entry doAfterTransactionCompletion post-update processing, passing it the
|
||||
// update state and the new version (if one).
|
||||
entry.postUpdate( instance, state, nextVersion );
|
||||
}
|
||||
|
@ -240,7 +239,11 @@ public final class EntityUpdateAction extends EntityAction {
|
|||
return veto;
|
||||
}
|
||||
|
||||
public void afterTransactionCompletion(boolean success) throws CacheException {
|
||||
protected boolean hasPostCommitEventListeners() {
|
||||
return getSession().getListeners().getPostCommitUpdateEventListeners().length>0;
|
||||
}
|
||||
|
||||
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) throws CacheException {
|
||||
EntityPersister persister = getPersister();
|
||||
if ( persister.hasCache() ) {
|
||||
|
||||
|
@ -266,10 +269,6 @@ public final class EntityUpdateAction extends EntityAction {
|
|||
postCommitUpdate();
|
||||
}
|
||||
|
||||
protected boolean hasPostCommitEventListeners() {
|
||||
return getSession().getListeners().getPostCommitUpdateEventListeners().length>0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,29 +34,43 @@ import java.io.Serializable;
|
|||
* together with required second-level cache management.
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Executable {
|
||||
/**
|
||||
* Called before executing any actions
|
||||
*/
|
||||
public void beforeExecutions() throws HibernateException;
|
||||
/**
|
||||
* Execute this action
|
||||
*/
|
||||
public void execute() throws HibernateException;
|
||||
/**
|
||||
* Do we need to retain this instance until after the
|
||||
* transaction completes?
|
||||
* @return false if this class defines a no-op
|
||||
* <tt>hasAfterTransactionCompletion()</tt>
|
||||
*/
|
||||
public boolean hasAfterTransactionCompletion();
|
||||
/**
|
||||
* Called after the transaction completes
|
||||
*/
|
||||
public void afterTransactionCompletion(boolean success) throws HibernateException;
|
||||
/**
|
||||
* What spaces (tables) are affected by this action?
|
||||
*
|
||||
* @return The spaces affected by this action.
|
||||
*/
|
||||
public Serializable[] getPropertySpaces();
|
||||
|
||||
/**
|
||||
* Called before executing any actions. Gives actions a chance to perform any preparation.
|
||||
*
|
||||
* @throws HibernateException Indicates a problem during preparation.
|
||||
*/
|
||||
public void beforeExecutions() throws HibernateException;
|
||||
|
||||
/**
|
||||
* Execute this action
|
||||
*
|
||||
* @throws HibernateException Indicates a problem during execution.
|
||||
*/
|
||||
public void execute() throws HibernateException;
|
||||
|
||||
/**
|
||||
* Get the after-transaction-completion process, if any, for this action.
|
||||
*
|
||||
* @return The after-transaction-completion process, or null if we have no
|
||||
* after-transaction-completion process
|
||||
*/
|
||||
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess();
|
||||
|
||||
/**
|
||||
* Get the before-transaction-completion process, if any, for this action.
|
||||
*
|
||||
* @return The before-transaction-completion process, or null if we have no
|
||||
* before-transaction-completion process
|
||||
*/
|
||||
public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess();
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ public class ThreadLocalSessionContext implements CurrentSessionContext {
|
|||
// method call to pass through since the real session
|
||||
// will complain by throwing an appropriate exception;
|
||||
// NOTE that allowing close() above has the same basic effect,
|
||||
// but we capture that there simply to perform the unbind...
|
||||
// but we capture that there simply to doAfterTransactionCompletion the unbind...
|
||||
}
|
||||
else if ( !realSession.getTransaction().isActive() ) {
|
||||
// limit the methods available if no transaction is active
|
||||
|
|
|
@ -287,7 +287,7 @@ public class MySQLDialect extends Dialect {
|
|||
|
||||
public Boolean performTemporaryTableDDLInIsolation() {
|
||||
// because we [drop *temporary* table...] we do not
|
||||
// have to perform these in isolation.
|
||||
// have to doAfterTransactionCompletion these in isolation.
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Iterator;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -49,6 +50,8 @@ import org.hibernate.action.EntityIdentityInsertAction;
|
|||
import org.hibernate.action.EntityInsertAction;
|
||||
import org.hibernate.action.EntityUpdateAction;
|
||||
import org.hibernate.action.Executable;
|
||||
import org.hibernate.action.AfterTransactionCompletionProcess;
|
||||
import org.hibernate.action.BeforeTransactionCompletionProcess;
|
||||
import org.hibernate.cache.CacheException;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
|
@ -82,7 +85,8 @@ public class ActionQueue {
|
|||
private ArrayList collectionUpdates;
|
||||
private ArrayList collectionRemovals;
|
||||
|
||||
private ArrayList executions;
|
||||
private AfterTransactionCompletionProcessQueue afterTransactionProcesses;
|
||||
private BeforeTransactionCompletionProcessQueue beforeTransactionProcesses;
|
||||
|
||||
/**
|
||||
* Constructs an action queue bound to the given session.
|
||||
|
@ -103,7 +107,8 @@ public class ActionQueue {
|
|||
collectionRemovals = new ArrayList( INIT_QUEUE_LIST_SIZE );
|
||||
collectionUpdates = new ArrayList( INIT_QUEUE_LIST_SIZE );
|
||||
|
||||
executions = new ArrayList( INIT_QUEUE_LIST_SIZE * 3 );
|
||||
afterTransactionProcesses = new AfterTransactionCompletionProcessQueue( session );
|
||||
beforeTransactionProcesses = new BeforeTransactionCompletionProcessQueue( session );
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
|
@ -145,8 +150,15 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public void addAction(BulkOperationCleanupAction cleanupAction) {
|
||||
// Add these directly to the executions queue
|
||||
executions.add( cleanupAction );
|
||||
registerProcess( cleanupAction.getAfterTransactionCompletionProcess() );
|
||||
}
|
||||
|
||||
public void registerProcess(AfterTransactionCompletionProcess process) {
|
||||
afterTransactionProcesses.register( process );
|
||||
}
|
||||
|
||||
public void registerProcess(BeforeTransactionCompletionProcess process) {
|
||||
beforeTransactionProcesses.register( process );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -189,29 +201,14 @@ public class ActionQueue {
|
|||
* @param success Was the transaction successful.
|
||||
*/
|
||||
public void afterTransactionCompletion(boolean success) {
|
||||
int size = executions.size();
|
||||
final boolean invalidateQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
try {
|
||||
Executable exec = ( Executable ) executions.get( i );
|
||||
try {
|
||||
exec.afterTransactionCompletion( success );
|
||||
}
|
||||
finally {
|
||||
if ( invalidateQueryCache ) {
|
||||
session.getFactory().getUpdateTimestampsCache().invalidate( exec.getPropertySpaces() );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( CacheException ce ) {
|
||||
log.error( "could not release a cache lock", ce );
|
||||
// continue loop
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new AssertionFailure( "Exception releasing cache locks", e );
|
||||
}
|
||||
}
|
||||
executions.clear();
|
||||
afterTransactionProcesses.afterTransactionCompletion( success );
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute any registered {@link BeforeTransactionCompletionProcess}
|
||||
*/
|
||||
public void beforeTransactionCompletion() {
|
||||
beforeTransactionProcesses.beforeTransactionCompletion();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,16 +264,18 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public void execute(Executable executable) {
|
||||
final boolean lockQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
|
||||
if ( executable.hasAfterTransactionCompletion() || lockQueryCache ) {
|
||||
executions.add( executable );
|
||||
try {
|
||||
executable.execute();
|
||||
}
|
||||
if ( lockQueryCache ) {
|
||||
session.getFactory()
|
||||
.getUpdateTimestampsCache()
|
||||
.preinvalidate( executable.getPropertySpaces() );
|
||||
finally {
|
||||
beforeTransactionProcesses.register( executable.getBeforeTransactionCompletionProcess() );
|
||||
if ( session.getFactory().getSettings().isQueryCacheEnabled() ) {
|
||||
final String[] spaces = (String[]) executable.getPropertySpaces();
|
||||
afterTransactionProcesses.addSpacesToInvalidate( spaces );
|
||||
session.getFactory().getUpdateTimestampsCache().preinvalidate( executable.getPropertySpaces() );
|
||||
}
|
||||
afterTransactionProcesses.register( executable.getAfterTransactionCompletionProcess() );
|
||||
}
|
||||
executable.execute();
|
||||
}
|
||||
|
||||
private void prepareActions(List queue) throws HibernateException {
|
||||
|
@ -376,7 +375,8 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
public boolean hasAfterTransactionActions() {
|
||||
return executions.size() > 0;
|
||||
// todo : method is not used anywhere; why is it here?
|
||||
return afterTransactionProcesses.processes.size() > 0;
|
||||
}
|
||||
|
||||
public boolean hasAnyQueuedActions() {
|
||||
|
@ -394,7 +394,7 @@ public class ActionQueue {
|
|||
*
|
||||
* @param oos The stream to which the action queue should get written
|
||||
*
|
||||
* @throws IOException
|
||||
* @throws IOException Indicates an error writing to the stream
|
||||
*/
|
||||
public void serialize(ObjectOutputStream oos) throws IOException {
|
||||
log.trace( "serializing action-queue" );
|
||||
|
@ -447,8 +447,12 @@ public class ActionQueue {
|
|||
* action queue
|
||||
*
|
||||
* @param ois The stream from which to read the action queue
|
||||
* @param session The session to which the action queue belongs
|
||||
*
|
||||
* @throws IOException
|
||||
* @return The deserialized action queue
|
||||
*
|
||||
* @throws IOException indicates a problem reading from the stream
|
||||
* @throws ClassNotFoundException Generally means we were unable to locate user classes.
|
||||
*/
|
||||
public static ActionQueue deserialize(
|
||||
ObjectInputStream ois,
|
||||
|
@ -500,6 +504,93 @@ public class ActionQueue {
|
|||
return rtn;
|
||||
}
|
||||
|
||||
private static class BeforeTransactionCompletionProcessQueue {
|
||||
private SessionImplementor session;
|
||||
private List processes = new ArrayList();
|
||||
|
||||
private BeforeTransactionCompletionProcessQueue(SessionImplementor session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void register(BeforeTransactionCompletionProcess process) {
|
||||
if ( process == null ) {
|
||||
return;
|
||||
}
|
||||
processes.add( process );
|
||||
}
|
||||
|
||||
public void beforeTransactionCompletion() {
|
||||
final int size = processes.size();
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
try {
|
||||
BeforeTransactionCompletionProcess process = ( BeforeTransactionCompletionProcess ) processes.get( i );
|
||||
process.doBeforeTransactionCompletion( session );
|
||||
}
|
||||
catch ( HibernateException he ) {
|
||||
throw he;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new AssertionFailure( "Unable to perform beforeTransactionCompletion callback", e );
|
||||
}
|
||||
}
|
||||
processes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static class AfterTransactionCompletionProcessQueue {
|
||||
private SessionImplementor session;
|
||||
private Set querySpacesToInvalidate = new HashSet();
|
||||
private List processes = new ArrayList( INIT_QUEUE_LIST_SIZE * 3 );
|
||||
|
||||
private AfterTransactionCompletionProcessQueue(SessionImplementor session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void addSpacesToInvalidate(String[] spaces) {
|
||||
if ( spaces == null ) {
|
||||
return;
|
||||
}
|
||||
for ( int i = 0, max = spaces.length; i < max; i++ ) {
|
||||
addSpaceToInvalidate( spaces[i] );
|
||||
}
|
||||
}
|
||||
|
||||
public void addSpaceToInvalidate(String space) {
|
||||
querySpacesToInvalidate.add( space );
|
||||
}
|
||||
|
||||
public void register(AfterTransactionCompletionProcess process) {
|
||||
if ( process == null ) {
|
||||
return;
|
||||
}
|
||||
processes.add( process );
|
||||
}
|
||||
|
||||
public void afterTransactionCompletion(boolean success) {
|
||||
final int size = processes.size();
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
try {
|
||||
AfterTransactionCompletionProcess process = ( AfterTransactionCompletionProcess ) processes.get( i );
|
||||
process.doAfterTransactionCompletion( success, session );
|
||||
}
|
||||
catch ( CacheException ce ) {
|
||||
log.error( "could not release a cache lock", ce );
|
||||
// continue loop
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
throw new AssertionFailure( "Exception releasing cache locks", e );
|
||||
}
|
||||
}
|
||||
processes.clear();
|
||||
|
||||
if ( session.getFactory().getSettings().isQueryCacheEnabled() ) {
|
||||
session.getFactory().getUpdateTimestampsCache().invalidate(
|
||||
( String[] ) querySpacesToInvalidate.toArray( new String[ querySpacesToInvalidate.size()] )
|
||||
);
|
||||
}
|
||||
querySpacesToInvalidate.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the insert actions using more hashes.
|
||||
|
@ -507,7 +598,6 @@ public class ActionQueue {
|
|||
* @author Jay Erb
|
||||
*/
|
||||
private class InsertActionSorter {
|
||||
|
||||
// the mapping of entity names to their latest batch numbers.
|
||||
private HashMap latestBatches = new HashMap();
|
||||
private HashMap entityBatchNumber;
|
||||
|
@ -567,10 +657,16 @@ public class ActionQueue {
|
|||
}
|
||||
|
||||
/**
|
||||
* Finds an acceptable batch for this entity to be a member.
|
||||
* Finds an acceptable batch for this entity to be a member as part of the {@link InsertActionSorter}
|
||||
*
|
||||
* @param action The action being sorted
|
||||
* @param entityName The name of the entity affected by the action
|
||||
*
|
||||
* @return An appropriate batch number; todo document this process better
|
||||
*/
|
||||
private Integer findBatchNumber(EntityInsertAction action,
|
||||
String entityName) {
|
||||
private Integer findBatchNumber(
|
||||
EntityInsertAction action,
|
||||
String entityName) {
|
||||
// loop through all the associated entities and make sure they have been
|
||||
// processed before the latest
|
||||
// batch associated with this entity type.
|
||||
|
|
|
@ -179,7 +179,7 @@ public class NativeSQLQueryPlan implements Serializable {
|
|||
( ( EventSource ) session ).getActionQueue().addAction( action );
|
||||
}
|
||||
else {
|
||||
action.afterTransactionCompletion( true );
|
||||
action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ public class Isolater {
|
|||
|
||||
connection = session.getBatcher().openConnection();
|
||||
|
||||
// perform the actual work
|
||||
// doAfterTransactionCompletion the actual work
|
||||
work.doWork( connection );
|
||||
|
||||
// if everything went ok, commit the transaction and close the obtained
|
||||
|
|
|
@ -287,7 +287,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
|
|||
dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
|
||||
}
|
||||
|
||||
// check nullability but do not perform command execute
|
||||
// check nullability but do not doAfterTransactionCompletion command execute
|
||||
// we'll use scheduled updates for that.
|
||||
new Nullability(session).checkNullability( values, persister, true );
|
||||
|
||||
|
|
|
@ -547,7 +547,7 @@ public class QueryTranslatorImpl implements FilterTranslator {
|
|||
if ( persister.isMultiTable() ) {
|
||||
// even here, if only properties mapped to the "base table" are referenced
|
||||
// in the set and where clauses, this could be handled by the BasicDelegate.
|
||||
// TODO : decide if it is better performance-wise to perform that check, or to simply use the MultiTableUpdateDelegate
|
||||
// TODO : decide if it is better performance-wise to doAfterTransactionCompletion that check, or to simply use the MultiTableUpdateDelegate
|
||||
return new MultiTableUpdateExecutor( walker );
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -245,7 +245,7 @@ public abstract class AbstractStatementExecutor implements StatementExecutor {
|
|||
( ( EventSource ) session ).getActionQueue().addAction( action );
|
||||
}
|
||||
else {
|
||||
action.afterTransactionCompletion( true );
|
||||
action.getAfterTransactionCompletionProcess().doAfterTransactionCompletion( true, session );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
|
|||
super( walker, log );
|
||||
|
||||
if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
|
||||
throw new HibernateException( "cannot perform multi-table deletes using dialect not supporting temp tables" );
|
||||
throw new HibernateException( "cannot doAfterTransactionCompletion multi-table deletes using dialect not supporting temp tables" );
|
||||
}
|
||||
|
||||
DeleteStatement deleteStatement = ( DeleteStatement ) walker.getAST();
|
||||
|
|
|
@ -63,7 +63,7 @@ public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
|
|||
super( walker, log );
|
||||
|
||||
if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
|
||||
throw new HibernateException( "cannot perform multi-table updates using dialect not supporting temp tables" );
|
||||
throw new HibernateException( "cannot doAfterTransactionCompletion multi-table updates using dialect not supporting temp tables" );
|
||||
}
|
||||
|
||||
UpdateStatement updateStatement = ( UpdateStatement ) walker.getAST();
|
||||
|
|
|
@ -333,7 +333,7 @@ public class FromClause extends HqlSqlWalkerNode implements HqlSqlTokenTypes, Di
|
|||
// the subquery has already been performed (meaning that for
|
||||
// theta-join dialects, the join conditions have already been moved
|
||||
// over to the where clause). A "simple" solution here might to
|
||||
// perform "join post processing" once for the entire query (including
|
||||
// doAfterTransactionCompletion "join post processing" once for the entire query (including
|
||||
// any subqueries) at one fell swoop
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
|
|||
return true;
|
||||
}
|
||||
|
||||
// otherwise, perform a "deep equivalence" check...
|
||||
// otherwise, doAfterTransactionCompletion a "deep equivalence" check...
|
||||
|
||||
if ( !target.getReturnedClass().isAssignableFrom( source.getReturnedClass() ) ) {
|
||||
return false;
|
||||
|
|
|
@ -423,6 +423,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
|
||||
public void beforeTransactionCompletion(Transaction tx) {
|
||||
log.trace( "before transaction completion" );
|
||||
actionQueue.beforeTransactionCompletion();
|
||||
if ( rootSession == null ) {
|
||||
try {
|
||||
interceptor.beforeTransactionCompletion(tx);
|
||||
|
@ -1185,7 +1186,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
|||
errorIfClosed();
|
||||
checkTransactionSynchStatus();
|
||||
if ( query == null ) {
|
||||
throw new IllegalArgumentException("attempt to perform delete-by-query with null query");
|
||||
throw new IllegalArgumentException("attempt to doAfterTransactionCompletion delete-by-query with null query");
|
||||
}
|
||||
|
||||
if ( log.isTraceEnabled() ) {
|
||||
|
|
|
@ -161,7 +161,7 @@ public class Expectations {
|
|||
|
||||
public static final Expectation NONE = new Expectation() {
|
||||
public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
|
||||
// explicitly perform no checking...
|
||||
// explicitly doAfterTransactionCompletion no checking...
|
||||
}
|
||||
|
||||
public int prepare(PreparedStatement statement) {
|
||||
|
|
|
@ -352,7 +352,7 @@ public abstract class Loader {
|
|||
throw JDBCExceptionHelper.convert(
|
||||
factory.getSQLExceptionConverter(),
|
||||
sqle,
|
||||
"could not perform sequential read of results (forward)",
|
||||
"could not doAfterTransactionCompletion sequential read of results (forward)",
|
||||
getSQLString()
|
||||
);
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ public abstract class Loader {
|
|||
}
|
||||
|
||||
// We call getKeyFromResultSet() here so that we can know the
|
||||
// key value upon which to perform the breaking logic. However,
|
||||
// key value upon which to doAfterTransactionCompletion the breaking logic. However,
|
||||
// it is also then called from getRowFromResultSet() which is certainly
|
||||
// not the most efficient. But the call here is needed, and there
|
||||
// currently is no other way without refactoring of the doQuery()/getRowFromResultSet()
|
||||
|
@ -419,7 +419,7 @@ public abstract class Loader {
|
|||
throw JDBCExceptionHelper.convert(
|
||||
factory.getSQLExceptionConverter(),
|
||||
sqle,
|
||||
"could not perform sequential read of results (forward)",
|
||||
"could not doAfterTransactionCompletion sequential read of results (forward)",
|
||||
getSQLString()
|
||||
);
|
||||
}
|
||||
|
@ -538,14 +538,14 @@ public abstract class Loader {
|
|||
// at the first physical row we are interested in loading
|
||||
resultSet.next();
|
||||
|
||||
// and perform the load
|
||||
// and doAfterTransactionCompletion the load
|
||||
return sequentialLoad( resultSet, session, queryParameters, returnProxies, keyToRead );
|
||||
}
|
||||
catch ( SQLException sqle ) {
|
||||
throw JDBCExceptionHelper.convert(
|
||||
factory.getSQLExceptionConverter(),
|
||||
sqle,
|
||||
"could not perform sequential read of results (forward)",
|
||||
"could not doAfterTransactionCompletion sequential read of results (forward)",
|
||||
getSQLString()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2794,7 +2794,7 @@ public abstract class AbstractEntityPersister
|
|||
// need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
|
||||
// first we need to locate the "loaded" state
|
||||
//
|
||||
// Note, it potentially could be a proxy, so perform the location the safe way...
|
||||
// Note, it potentially could be a proxy, so doAfterTransactionCompletion the location the safe way...
|
||||
EntityKey key = new EntityKey( id, this, session.getEntityMode() );
|
||||
Object entity = session.getPersistenceContext().getEntity( key );
|
||||
if ( entity != null ) {
|
||||
|
|
|
@ -120,7 +120,7 @@ public abstract class CollectionType extends AbstractType implements Association
|
|||
}
|
||||
|
||||
public int getHashCode(Object x, EntityMode entityMode) {
|
||||
throw new UnsupportedOperationException( "cannot perform lookups on collections" );
|
||||
throw new UnsupportedOperationException( "cannot doAfterTransactionCompletion lookups on collections" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -494,7 +494,7 @@ public class CompositeIdWithGeneratorTest extends FunctionalTestCase {
|
|||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
|
||||
// perform a find to show that it will wire together fine
|
||||
// doAfterTransactionCompletion a find to show that it will wire together fine
|
||||
PurchaseRecord foundRecord = (PurchaseRecord) s.get(PurchaseRecord.class,
|
||||
new PurchaseRecord.Id(foundPurchaseNumber, foundPurchaseSequence)
|
||||
);
|
||||
|
|
|
@ -527,14 +527,14 @@ public class ASTParserLoadingTest extends FunctionalTestCase {
|
|||
assertEquals( 1, types.length );
|
||||
assertTrue( types[0] instanceof ComponentType );
|
||||
|
||||
// Test the ability to perform comparisions between component values
|
||||
// Test the ability to doAfterTransactionCompletion comparisions between component values
|
||||
s.createQuery( "from Human h where h.name = h.name" ).list();
|
||||
s.createQuery( "from Human h where h.name = :name" ).setParameter( "name", new Name() ).list();
|
||||
s.createQuery( "from Human where name = :name" ).setParameter( "name", new Name() ).list();
|
||||
s.createQuery( "from Human h where :name = h.name" ).setParameter( "name", new Name() ).list();
|
||||
s.createQuery( "from Human h where :name <> h.name" ).setParameter( "name", new Name() ).list();
|
||||
|
||||
// Test the ability to perform comparisions between a component and an explicit row-value
|
||||
// Test the ability to doAfterTransactionCompletion comparisions between a component and an explicit row-value
|
||||
s.createQuery( "from Human h where h.name = ('John', 'X', 'Doe')" ).list();
|
||||
s.createQuery( "from Human h where ('John', 'X', 'Doe') = h.name" ).list();
|
||||
s.createQuery( "from Human h where ('John', 'X', 'Doe') <> h.name" ).list();
|
||||
|
|
|
@ -74,7 +74,7 @@ public class JPALockTest extends AbstractJPATest {
|
|||
|
||||
Long itemId = item.getId();
|
||||
|
||||
// perform the isolated update
|
||||
// doAfterTransactionCompletion the isolated update
|
||||
s1 = getSessions().openSession();
|
||||
t1 = s1.beginTransaction();
|
||||
item = (Item) s1.get( Item.class, itemId );
|
||||
|
|
Loading…
Reference in New Issue