Skip to content

Commit a41506f

Browse files
committed
HHH-4034 - Update org.hibernate.action.BulkOperationCleanupAction to use new Region cache APIs
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17084 1b8cb986-b30d-0410-93ca-fae66ebed9b2
1 parent b339e33 commit a41506f

File tree

8 files changed

+208
-103
lines changed

8 files changed

+208
-103
lines changed

cache-jbosscache/src/test/java/org/hibernate/test/cache/jbc/functional/CacheTestCaseBase.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ public CacheTestCaseBase(String x) {
5353
}
5454

5555
public String[] getMappings() {
56-
return new String[] { "cache/jbc2/functional/Item.hbm.xml", "cache/jbc2/functional/Customer.hbm.xml", "cache/jbc2/functional/Contact.hbm.xml" };
56+
return new String[] {
57+
"cache/jbc/functional/Item.hbm.xml",
58+
"cache/jbc/functional/Customer.hbm.xml",
59+
"cache/jbc/functional/Contact.hbm.xml"
60+
};
5761
}
5862

5963
public void configure(Configuration cfg) {
@@ -96,7 +100,7 @@ public String getCacheConcurrencyStrategy() {
96100
/**
97101
* Apply any region-factory specific configurations.
98102
*
99-
* @param the Configuration to update.
103+
* @param cfg the Configuration to update.
100104
*/
101105
protected abstract void configureCacheFactory(Configuration cfg);
102106

cache-jbosscache/src/test/java/org/hibernate/test/cache/jbc/functional/PessimisticSessionRefreshTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ protected String getEntityCacheConfigName() {
118118
@Override
119119
public String[] getMappings()
120120
{
121-
return new String[] { "cache/jbc2/functional/classloader/Account.hbm.xml" };
121+
return new String[] { "cache/jbc/functional/classloader/Account.hbm.xml" };
122122
}
123123

124124
@Override

cache-jbosscache/src/test/java/org/hibernate/test/cache/jbc/functional/classloader/PessimisticIsolatedClassLoaderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ protected boolean getUseQueryCache()
105105
@Override
106106
public String[] getMappings()
107107
{
108-
return new String[] { "cache/jbc2/functional/classloader/Account.hbm.xml" };
108+
return new String[] { "cache/jbc/functional/classloader/Account.hbm.xml" };
109109
}
110110

111111
@Override

cache-jbosscache/src/test/java/org/hibernate/test/cache/jbc/functional/util/IsolatedCacheTestSetup.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
public class IsolatedCacheTestSetup extends SelectedClassnameClassLoaderTestSetup
3232
{
3333

34-
public static final String DEF_CACHE_FACTORY_RESOURCE = "org/hibernate/cache/jbc2/builder/jbc2-configs.xml";
35-
public static final String DEF_JGROUPS_RESOURCE = "org/hibernate/cache/jbc2/builder/jgroups-stacks.xml";
34+
public static final String DEF_CACHE_FACTORY_RESOURCE = "org/hibernate/cache/jbc/builder/jbc2-configs.xml";
35+
public static final String DEF_JGROUPS_RESOURCE = "org/hibernate/cache/jbc/builder/jgroups-stacks.xml";
3636

3737
private String[] isolatedClasses;
3838
private String cacheConfig;

cache-jbosscache/src/test/java/org/hibernate/test/util/CacheManagerTestSetup.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
*/
3737
public class CacheManagerTestSetup extends TestSetup
3838
{
39-
public static final String DEF_CACHE_FACTORY_RESOURCE = "org/hibernate/cache/jbc2/builder/jbc2-configs.xml";
40-
public static final String DEF_JGROUPS_RESOURCE = "org/hibernate/cache/jbc2/builder/jgroups-stacks.xml";
39+
public static final String DEF_CACHE_FACTORY_RESOURCE = "org/hibernate/cache/jbc/builder/jbc2-configs.xml";
40+
public static final String DEF_JGROUPS_RESOURCE = "org/hibernate/cache/jbc/builder/jgroups-stacks.xml";
4141

4242
private final String jbcConfig;
4343
private final String jgConfig;

core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java

Lines changed: 144 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@
2525
package org.hibernate.action;
2626

2727
import org.hibernate.HibernateException;
28+
import org.hibernate.cache.access.SoftLock;
29+
import org.hibernate.cache.access.EntityRegionAccessStrategy;
30+
import org.hibernate.cache.access.CollectionRegionAccessStrategy;
2831
import org.hibernate.persister.entity.EntityPersister;
2932
import org.hibernate.persister.entity.Queryable;
33+
import org.hibernate.persister.collection.CollectionPersister;
3034
import org.hibernate.engine.SessionFactoryImplementor;
3135
import org.hibernate.engine.SessionImplementor;
3236

@@ -36,49 +40,84 @@
3640
import java.util.Iterator;
3741
import java.util.HashSet;
3842
import java.util.ArrayList;
43+
import java.util.Arrays;
3944

4045
/**
41-
* Implementation of BulkOperationCleanupAction.
46+
* An {@link org.hibernate.engine.ActionQueue} {@link Executable} for ensuring
47+
* shared cache cleanup in relation to performed bulk HQL queries.
48+
* <p/>
49+
* NOTE: currently this executes for <tt>INSERT</tt> queries as well as
50+
* <tt>UPDATE</tt> and <tt>DELETE</tt> queries. For <tt>INSERT</tt> it is
51+
* really not needed as we'd have no invalid entity/collection data to
52+
* cleanup (we'd still nee to invalidate the appropriate update-timestamps
53+
* regions) as a result of this query.
4254
*
4355
* @author Steve Ebersole
4456
*/
4557
public class BulkOperationCleanupAction implements Executable, Serializable {
46-
47-
private final SessionImplementor session;
48-
49-
private final Set affectedEntityNames = new HashSet();
50-
private final Set affectedCollectionRoles = new HashSet();
51-
private final Serializable[] spaces;
52-
53-
public BulkOperationCleanupAction(SessionImplementor session, Queryable[] affectedQueryables) {
54-
this.session = session;
55-
// TODO : probably better to calculate these and pass them in, as it'll be more performant
58+
private final Serializable[] affectedTableSpaces;
59+
60+
private final Set entityCleanups = new HashSet();
61+
private final Set collectionCleanups = new HashSet();
62+
63+
/**
64+
* Constructs an action to cleanup "affected cache regions" based on the
65+
* affected entity persisters. The affected regions are defined as the
66+
* region (if any) of the entity persisters themselves, plus the
67+
* collection regions for any collection in which those entity
68+
* persisters participate as elements/keys/etc.
69+
*
70+
* @param session The session to which this request is tied.
71+
* @param affectedQueryables The affected entity persisters.
72+
*/
73+
public BulkOperationCleanupAction(
74+
SessionImplementor session,
75+
Queryable[] affectedQueryables) {
76+
SessionFactoryImplementor factory = session.getFactory();
5677
ArrayList tmpSpaces = new ArrayList();
5778
for ( int i = 0; i < affectedQueryables.length; i++ ) {
79+
tmpSpaces.addAll( Arrays.asList( affectedQueryables[i].getQuerySpaces() ) );
5880
if ( affectedQueryables[i].hasCache() ) {
59-
affectedEntityNames.add( affectedQueryables[i].getEntityName() );
81+
entityCleanups.add(
82+
new EntityCleanup(
83+
affectedQueryables[i].getCacheAccessStrategy()
84+
)
85+
);
6086
}
61-
Set roles = session.getFactory().getCollectionRolesByEntityParticipant( affectedQueryables[i].getEntityName() );
87+
Set roles = factory.getCollectionRolesByEntityParticipant( affectedQueryables[i].getEntityName() );
6288
if ( roles != null ) {
63-
affectedCollectionRoles.addAll( roles );
64-
}
65-
for ( int y = 0; y < affectedQueryables[i].getQuerySpaces().length; y++ ) {
66-
tmpSpaces.add( affectedQueryables[i].getQuerySpaces()[y] );
89+
Iterator itr = roles.iterator();
90+
while ( itr.hasNext() ) {
91+
String role = ( String ) itr.next();
92+
CollectionPersister collectionPersister = factory.getCollectionPersister( role );
93+
if ( collectionPersister.hasCache() ) {
94+
collectionCleanups.add(
95+
new CollectionCleanup(
96+
collectionPersister.getCacheAccessStrategy()
97+
)
98+
);
99+
}
100+
}
67101
}
68102
}
69-
this.spaces = new Serializable[ tmpSpaces.size() ];
70-
for ( int i = 0; i < tmpSpaces.size(); i++ ) {
71-
this.spaces[i] = ( Serializable ) tmpSpaces.get( i );
72-
}
103+
104+
this.affectedTableSpaces = ( Serializable[] ) tmpSpaces.toArray( new Serializable[ tmpSpaces.size() ] );
73105
}
74-
75-
/** Create an action that will evict collection and entity regions based on queryspaces (table names).
76-
* TODO: cache the autodetected information and pass it in instead.
77-
**/
78-
public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces) {
79-
this.session = session;
80-
81-
Set tmpSpaces = new HashSet(querySpaces);
106+
107+
/**
108+
* Constructs an action to cleanup "affected cache regions" based on a
109+
* set of affected table spaces. This differs from {@link #BulkOperationCleanupAction(SessionImplementor, Queryable[])}
110+
* in that here we have the affected <strong>table names</strong>. From those
111+
* we deduce the entity persisters whcih are affected based on the defined
112+
* {@link EntityPersister#getQuerySpaces() table spaces}; and from there, we
113+
* determine the affected collection regions based on any collections
114+
* in which those entity persisters participate as elements/keys/etc.
115+
*
116+
* @param session The session to which this request is tied.
117+
* @param tableSpaces The table spaces.
118+
*/
119+
public BulkOperationCleanupAction(SessionImplementor session, Set tableSpaces) {
120+
Set tmpSpaces = new HashSet(tableSpaces);
82121
SessionFactoryImplementor factory = session.getFactory();
83122
Iterator iterator = factory.getAllClassMetadata().entrySet().iterator();
84123
while ( iterator.hasNext() ) {
@@ -87,54 +126,84 @@ public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces) {
87126
EntityPersister persister = factory.getEntityPersister( entityName );
88127
Serializable[] entitySpaces = persister.getQuerySpaces();
89128

90-
if (affectedEntity( querySpaces, entitySpaces )) {
129+
if ( affectedEntity( tableSpaces, entitySpaces ) ) {
130+
tmpSpaces.addAll( Arrays.asList( entitySpaces ) );
91131
if ( persister.hasCache() ) {
92-
affectedEntityNames.add( persister.getEntityName() );
132+
entityCleanups.add(
133+
new EntityCleanup(
134+
persister.getCacheAccessStrategy()
135+
)
136+
);
93137
}
94138
Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() );
95139
if ( roles != null ) {
96-
affectedCollectionRoles.addAll( roles );
97-
}
98-
for ( int y = 0; y < entitySpaces.length; y++ ) {
99-
tmpSpaces.add( entitySpaces[y] );
140+
Iterator itr = roles.iterator();
141+
while ( itr.hasNext() ) {
142+
String role = ( String ) itr.next();
143+
CollectionPersister collectionPersister = factory.getCollectionPersister( role );
144+
if ( collectionPersister.hasCache() ) {
145+
collectionCleanups.add(
146+
new CollectionCleanup(
147+
collectionPersister.getCacheAccessStrategy()
148+
)
149+
);
150+
}
151+
}
100152
}
101153
}
102-
103154
}
104-
this.spaces = (Serializable[]) tmpSpaces.toArray( new Serializable[tmpSpaces.size()] );
155+
156+
this.affectedTableSpaces = ( Serializable[] ) tmpSpaces.toArray( new Serializable[ tmpSpaces.size() ] );
105157
}
106158

107159

108-
/** returns true if no queryspaces or if there are a match */
109-
private boolean affectedEntity(Set querySpaces, Serializable[] entitySpaces) {
110-
if(querySpaces==null || querySpaces.isEmpty()) {
160+
/**
161+
* Check to determine whether the table spaces reported by an entity
162+
* persister match against the defined affected table spaces.
163+
*
164+
* @param affectedTableSpaces The table spaces reported to be affected by
165+
* the query.
166+
* @param checkTableSpaces The table spaces (from the entity persister)
167+
* to check against the affected table spaces.
168+
*
169+
* @return True if there are affected table spaces and any of the incoming
170+
* check table spaces occur in that set.
171+
*/
172+
private boolean affectedEntity(
173+
Set affectedTableSpaces,
174+
Serializable[] checkTableSpaces) {
175+
if ( affectedTableSpaces == null || affectedTableSpaces.isEmpty() ) {
111176
return true;
112177
}
113-
114-
for ( int i = 0; i < entitySpaces.length; i++ ) {
115-
if ( querySpaces.contains( entitySpaces[i] ) ) {
178+
179+
for ( int i = 0; i < checkTableSpaces.length; i++ ) {
180+
if ( affectedTableSpaces.contains( checkTableSpaces[i] ) ) {
116181
return true;
117182
}
118183
}
119184
return false;
120185
}
121186

122-
public void init() {
123-
evictEntityRegions();
124-
evictCollectionRegions();
187+
public Serializable[] getPropertySpaces() {
188+
return affectedTableSpaces;
125189
}
126190

127191
public boolean hasAfterTransactionCompletion() {
128192
return true;
129193
}
130194

131195
public void afterTransactionCompletion(boolean success) throws HibernateException {
132-
evictEntityRegions();
133-
evictCollectionRegions();
134-
}
196+
Iterator itr = entityCleanups.iterator();
197+
while ( itr.hasNext() ) {
198+
final EntityCleanup cleanup = ( EntityCleanup ) itr.next();
199+
cleanup.release();
200+
}
135201

136-
public Serializable[] getPropertySpaces() {
137-
return spaces;
202+
itr = collectionCleanups.iterator();
203+
while ( itr.hasNext() ) {
204+
final CollectionCleanup cleanup = ( CollectionCleanup ) itr.next();
205+
cleanup.release();
206+
}
138207
}
139208

140209
public void beforeExecutions() throws HibernateException {
@@ -145,23 +214,33 @@ public void execute() throws HibernateException {
145214
// nothing to do
146215
}
147216

148-
private void evictEntityRegions() {
149-
if ( affectedEntityNames != null ) {
150-
Iterator itr = affectedEntityNames.iterator();
151-
while ( itr.hasNext() ) {
152-
final String entityName = ( String ) itr.next();
153-
session.getFactory().evictEntity( entityName );
154-
}
217+
private static class EntityCleanup {
218+
private final EntityRegionAccessStrategy cacheAccess;
219+
private final SoftLock cacheLock;
220+
221+
private EntityCleanup(EntityRegionAccessStrategy cacheAccess) {
222+
this.cacheAccess = cacheAccess;
223+
this.cacheLock = cacheAccess.lockRegion();
224+
cacheAccess.removeAll();
225+
}
226+
227+
private void release() {
228+
cacheAccess.unlockRegion( cacheLock );
155229
}
156230
}
157231

158-
private void evictCollectionRegions() {
159-
if ( affectedCollectionRoles != null ) {
160-
Iterator itr = affectedCollectionRoles.iterator();
161-
while ( itr.hasNext() ) {
162-
final String roleName = ( String ) itr.next();
163-
session.getFactory().evictCollection( roleName );
164-
}
232+
private static class CollectionCleanup {
233+
private final CollectionRegionAccessStrategy cacheAccess;
234+
private final SoftLock cacheLock;
235+
236+
private CollectionCleanup(CollectionRegionAccessStrategy cacheAccess) {
237+
this.cacheAccess = cacheAccess;
238+
this.cacheLock = cacheAccess.lockRegion();
239+
cacheAccess.removeAll();
240+
}
241+
242+
private void release() {
243+
cacheAccess.unlockRegion( cacheLock );
165244
}
166245
}
167246
}

0 commit comments

Comments
 (0)