From b82dee53595f721544afec08d5f63d7c7e52662c Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Mon, 10 Aug 2026 14:50:19 -0700 Subject: [PATCH 1/3] Fix cache population check --- .../org/labkey/experiment/api/ExperimentServiceImpl.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java index 50e98716caa..9812384984f 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java @@ -1894,12 +1894,8 @@ public ExpDataClassImpl getDataClass(long rowId) dataClass = new ExpDataClassImpl(dc); } - if (null != dataClass) - { - Container dcContainer = dataClass.getContainer(); - if (dcContainer != null && dcContainer.getId().equals(containerId)) - dataClassLsidCache.put(lsid, dataClass.getContainer().getId()); - } + if (null != dataClass && null == containerId) + dataClassLsidCache.put(lsid, dataClass.getContainer().getId()); return dataClass; } From df49736abd7f09e16962ff86ff304582cb3c56fd Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Mon, 10 Aug 2026 16:16:53 -0700 Subject: [PATCH 2/3] Test updates --- .../api/ExpDataClassDataTestCase.jsp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp index aea05c07c71..a9cf040aa27 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp @@ -1189,18 +1189,25 @@ public void testDataClassLsidCache() throws Exception // first lookup populates the mapping, second is served from the container's data class cache for (int i = 0; i < 2; i++) { - ExpDataClass fromProject = ExperimentService.get().getDataClass(projectLsid); + ExpDataClassImpl fromProject = ExperimentServiceImpl.get().getDataClass(projectLsid); assertNotNull("Lookup " + i + " by LSID should resolve the data class", fromProject); assertEquals("lsidCacheProject", fromProject.getName()); assertEquals(projectDataClass.getRowId(), fromProject.getRowId()); assertEquals(c.getId(), fromProject.getContainer().getId()); - ExpDataClass fromSub = ExperimentService.get().getDataClass(subLsid); + ExpDataClassImpl fromSub = ExperimentServiceImpl.get().getDataClass(subLsid); assertNotNull("Lookup " + i + " by LSID should resolve the subfolder data class", fromSub); assertEquals("lsidCacheSub", fromSub.getName()); assertEquals(sub.getId(), fromSub.getContainer().getId()); } + assertSame("LSID lookup should be served from the data class cache", + ExperimentServiceImpl.get().getDataClass(c, "lsidCacheProject").getDataObject(), + ExperimentServiceImpl.get().getDataClass(projectLsid).getDataObject()); + assertSame("Subfolder LSID lookup should be served from the data class cache", + ExperimentServiceImpl.get().getDataClass(sub, "lsidCacheSub").getDataObject(), + ExperimentServiceImpl.get().getDataClass(subLsid).getDataObject()); + projectDataClass.delete(_user); assertNull("Deleted data class should not resolve from a stale LSID mapping", ExperimentService.get().getDataClass(projectLsid)); assertNotNull("Sibling data class should be unaffected", ExperimentService.get().getDataClass(subLsid)); @@ -1223,10 +1230,13 @@ public void testFailedDataClassUpdateDoesNotCorruptCache() throws Exception helper.insertRows(c, rows, child.getName()); // warm the mapping so the second lookup comes back from the container's data class cache - assertNotNull(ExperimentService.get().getDataClass(child.getLSID())); - final ExpDataClass toUpdate = ExperimentService.get().getDataClass(child.getLSID()); + final ExpDataClassImpl toUpdate = ExperimentServiceImpl.get().getDataClass(child.getLSID()); assertNotNull(toUpdate); + assertSame("Update target should wrap the cached DataClass", + ExperimentServiceImpl.get().getDataClass(c, "failedUpdateChild").getDataObject(), + toUpdate.getDataObject()); + Map parentAlias = new HashMap<>(); parentAlias.put("inputType", ExperimentJSONConverter.DATA_INPUTS_ALIAS_PREFIX + "failedUpdateParent"); parentAlias.put("required", true); From 6b9bc92320524023b6ccb0cc309a9d6885df3ea2 Mon Sep 17 00:00:00 2001 From: labkey-nicka Date: Mon, 10 Aug 2026 16:17:38 -0700 Subject: [PATCH 3/3] Missed --- .../src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp | 1 + 1 file changed, 1 insertion(+) diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp index a9cf040aa27..f82c663c0d0 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp @@ -1230,6 +1230,7 @@ public void testFailedDataClassUpdateDoesNotCorruptCache() throws Exception helper.insertRows(c, rows, child.getName()); // warm the mapping so the second lookup comes back from the container's data class cache + assertNotNull(ExperimentServiceImpl.get().getDataClass(child.getLSID())); final ExpDataClassImpl toUpdate = ExperimentServiceImpl.get().getDataClass(child.getLSID()); assertNotNull(toUpdate);