Skip to content

Commit

Permalink
Merge pull request DSpace#3253 from atmire/uncache-entities
Browse files Browse the repository at this point in the history
Add Context method to uncache all entities
  • Loading branch information
tdonohue authored Dec 19, 2024
2 parents 1abf89f + 8ea664a commit 97dd1e0
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 12 deletions.
14 changes: 13 additions & 1 deletion dspace-api/src/main/java/org/dspace/core/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,19 @@ public <E extends ReloadableEntity> E reloadEntity(E entity) throws SQLException
}

/**
* Remove an entity from the cache. This is necessary when batch processing a large number of items.
* Remove all entities from the cache and reload the current user entity. This is useful when batch processing
* a large number of entities when the calling code requires the cache to be completely cleared before continuing.
*
* @throws SQLException if a database error occurs.
*/
public void uncacheEntities() throws SQLException {
dbConnection.uncacheEntities();
reloadContextBoundEntities();
}

/**
* Remove an entity from the cache. This is useful when batch processing a large number of entities
* when the calling code needs to retain some items in the cache while removing others.
*
* @param entity The entity to reload
* @param <E> The class of the entity. The entity must implement the {@link ReloadableEntity} interface.
Expand Down
32 changes: 21 additions & 11 deletions dspace-api/src/main/java/org/dspace/core/DBConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,28 +124,38 @@ public interface DBConnection<T> {
public long getCacheSize() throws SQLException;

/**
* Reload a DSpace object from the database. This will make sure the object
* Reload an entity from the database. This will make sure the object
* is valid and stored in the cache. The returned object should be used
* henceforth instead of the passed object.
*
* @param <E> type of {@link entity}
* @param entity The DSpace object to reload
* @param <E> type of entity.
* @param entity The entity to reload.
* @return the reloaded entity.
* @throws java.sql.SQLException passed through.
* @throws SQLException passed through.
*/
public <E extends ReloadableEntity> E reloadEntity(E entity) throws SQLException;

/**
* Remove a DSpace object from the session cache when batch processing a
* large number of objects.
* Remove all entities from the session cache.
*
* <p>Objects removed from cache are not saved in any way. Therefore, if you
* have modified an object, you should be sure to {@link commit()} changes
* <p>Entities removed from cache are not saved in any way. Therefore, if you
* have modified any entities, you should be sure to {@link #commit()} changes
* before calling this method.
*
* @param <E> Type of {@link entity}
* @param entity The DSpace object to decache.
* @throws java.sql.SQLException passed through.
* @throws SQLException passed through.
*/
public void uncacheEntities() throws SQLException;

/**
* Remove an entity from the session cache.
*
* <p>Entities removed from cache are not saved in any way. Therefore, if you
* have modified the entity, you should be sure to {@link #commit()} changes
* before calling this method.
*
* @param <E> Type of entity.
* @param entity The entity to decache.
* @throws SQLException passed through.
*/
public <E extends ReloadableEntity> void uncacheEntity(E entity) throws SQLException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ private void configureDatabaseMode() throws SQLException {
}
}

@Override
public void uncacheEntities() throws SQLException {
getSession().clear();
}

/**
* Evict an entity from the hibernate cache.
* <P>
Expand Down
25 changes: 25 additions & 0 deletions dspace-api/src/test/java/org/dspace/core/ContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -558,4 +558,29 @@ protected void init() {
cleanupContext(instance);
}

@Test
public void testUncacheEntities() throws Throwable {
// To set up the test, ensure the cache contains more than the current user entity
groupService.findByName(context, Group.ANONYMOUS);
assertTrue("Cache size should be greater than one", context.getDBConnection().getCacheSize() > 1);

context.uncacheEntities();

assertThat("Cache size should be one (current user)", context.getDBConnection().getCacheSize(), equalTo(1L));
context.reloadEntity(context.getCurrentUser());
assertThat("Cache should only contain the current user", context.getDBConnection().getCacheSize(), equalTo(1L));
}

@Test
public void testUncacheEntity() throws Throwable {
// Remember the cache size after loading an entity
Group group = groupService.findByName(context, Group.ANONYMOUS);
long oldCacheSize = context.getDBConnection().getCacheSize();

// Uncache the entity
context.uncacheEntity(group);

long newCacheSize = context.getDBConnection().getCacheSize();
assertThat("Cache size should be reduced by one", newCacheSize, equalTo(oldCacheSize - 1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,28 @@ public void testReloadEntityAfterCommit() throws SQLException {
.contains(person));
}

/**
* Test of uncacheEntities method
*/
@Test
public void testUncacheEntities() throws SQLException {
// Get DBConnection associated with DSpace Context
HibernateDBConnection dbConnection = (HibernateDBConnection) context.getDBConnection();
EPerson person = context.getCurrentUser();

assertTrue("Current user should be cached in session", dbConnection.getSession()
.contains(person));

dbConnection.uncacheEntities();
assertFalse("Current user should be gone from cache", dbConnection.getSession()
.contains(person));

// Test ability to reload an uncached entity
person = dbConnection.reloadEntity(person);
assertTrue("Current user should be cached back in session", dbConnection.getSession()
.contains(person));
}

/**
* Test of uncacheEntity method
*/
Expand Down

0 comments on commit 97dd1e0

Please sign in to comment.