diff --git a/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java b/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java index 7dae4a9d9812..f57ceb474e39 100644 --- a/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java +++ b/dspace-api/src/main/java/org/dspace/core/HibernateDBConnection.java @@ -301,7 +301,13 @@ public void uncacheEntity(E entity) throws SQLExcep } else if (entity instanceof Bundle) { Bundle bundle = (Bundle) entity; - if (Hibernate.isInitialized(bundle.getBitstreams())) { + // Bundle.getBitstreams() creates a defensive copy via new ArrayList<>(bitstreams) + // which iterates the Hibernate proxy, triggering lazy loading unconditionally. + // Unlike Item.getBundles() which returns the raw proxy, we cannot safely call + // getBitstreams() when the bundle is detached from the session. + // Guard with session.contains(): if the bundle is still managed, + // lazy loading will work; if detached (e.g. after session.clear()), we skip. + if (getSession().contains(bundle)) { for (Bitstream bitstream : Utils.emptyIfNull(bundle.getBitstreams())) { uncacheEntity(bitstream); } diff --git a/dspace-api/src/test/java/org/dspace/workflow/WorkflowCurationIT.java b/dspace-api/src/test/java/org/dspace/workflow/WorkflowCurationIT.java index 66dd2cee807f..8a07aaf7141f 100644 --- a/dspace-api/src/test/java/org/dspace/workflow/WorkflowCurationIT.java +++ b/dspace-api/src/test/java/org/dspace/workflow/WorkflowCurationIT.java @@ -22,6 +22,7 @@ import org.dspace.content.Community; import org.dspace.content.MetadataValue; import org.dspace.content.service.ItemService; +import org.dspace.core.LegacyPluginServiceImpl; import org.dspace.ctask.testing.MarkerTask; import org.dspace.eperson.EPerson; import org.dspace.util.DSpaceConfigurationInitializer; @@ -29,6 +30,7 @@ import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -46,6 +48,8 @@ public class WorkflowCurationIT extends AbstractIntegrationTestWithDatabase { @Inject private ItemService itemService; + @Autowired + private LegacyPluginServiceImpl legacyPluginService; /** * Basic smoke test of a curation task attached to a workflow step. @@ -57,6 +61,11 @@ public void curationTest() throws Exception { context.turnOffAuthorisationSystem(); + // Reset the named plugin cache to avoid pollution from other tests + // (e.g. CreateMissingIdentifiersIT) that may have run before this one. + // See https://github.com/DSpace/DSpace/issues/8533 + legacyPluginService.clearNamedPluginClasses(); + //** GIVEN ** // A submitter;