mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge pull request #10182 from tdonohue/port_9340_to_8x
[Port dspace-8_x] Bugfix: Enforce unique item id in workspace table (#9340)
This commit is contained in:
@@ -178,6 +178,14 @@ public class WorkspaceItemServiceImpl implements WorkspaceItemService {
|
||||
|
||||
@Override
|
||||
public WorkspaceItem create(Context c, WorkflowItem workflowItem) throws SQLException, AuthorizeException {
|
||||
WorkspaceItem potentialDuplicate = findByItem(c, workflowItem.getItem());
|
||||
if (potentialDuplicate != null) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"A workspace item referring to item %s already exists (%d)",
|
||||
workflowItem.getItem().getID(),
|
||||
potentialDuplicate.getID()
|
||||
));
|
||||
}
|
||||
WorkspaceItem workspaceItem = workspaceItemDAO.create(c, new WorkspaceItem());
|
||||
workspaceItem.setItem(workflowItem.getItem());
|
||||
workspaceItem.setCollection(workflowItem.getCollection());
|
||||
|
@@ -0,0 +1,21 @@
|
||||
--
|
||||
-- The contents of this file are subject to the license and copyright
|
||||
-- detailed in the LICENSE and NOTICE files at the root of the source
|
||||
-- tree and available online at
|
||||
--
|
||||
-- http://www.dspace.org/license/
|
||||
--
|
||||
|
||||
-- In the workspaceitem table, if there are multiple rows referring to the same item ID, keep only the first of them.
|
||||
DELETE FROM workspaceitem WHERE EXISTS (
|
||||
SELECT item_id
|
||||
FROM workspaceitem
|
||||
GROUP BY item_id
|
||||
HAVING COUNT(workspace_item_id) > 1
|
||||
) AND workspaceitem.workspace_item_id NOT IN (
|
||||
SELECT MIN(workspace_item_id) AS workspace_item_id
|
||||
FROM workspaceitem
|
||||
GROUP BY item_id
|
||||
);
|
||||
-- Identify which rows have duplicates, and compute their replacements.
|
||||
ALTER TABLE workspaceitem ADD CONSTRAINT unique_item_id UNIQUE(item_id);
|
@@ -0,0 +1,21 @@
|
||||
--
|
||||
-- The contents of this file are subject to the license and copyright
|
||||
-- detailed in the LICENSE and NOTICE files at the root of the source
|
||||
-- tree and available online at
|
||||
--
|
||||
-- http://www.dspace.org/license/
|
||||
--
|
||||
|
||||
-- In the workspaceitem table, if there are multiple rows referring to the same item ID, keep only the first of them.
|
||||
WITH dedup AS (
|
||||
SELECT item_id, MIN(workspace_item_id) AS workspace_item_id
|
||||
FROM workspaceitem
|
||||
GROUP BY item_id
|
||||
HAVING COUNT(workspace_item_id) > 1
|
||||
)
|
||||
DELETE FROM workspaceitem
|
||||
USING dedup
|
||||
WHERE workspaceitem.item_id = dedup.item_id AND workspaceitem.workspace_item_id <> dedup.workspace_item_id;
|
||||
|
||||
-- Enforce uniqueness of item_id in workspaceitem table.
|
||||
ALTER TABLE workspaceitem ADD CONSTRAINT unique_item_id UNIQUE(item_id);
|
@@ -12,6 +12,7 @@ import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -39,6 +40,7 @@ import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.eperson.service.EPersonService;
|
||||
import org.dspace.workflow.MockWorkflowItem;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -468,4 +470,14 @@ public class WorkspaceItemTest extends AbstractUnitTest {
|
||||
assertTrue("testSetPublishedBefore 0", wi.isPublishedBefore());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicateItemID() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
Item item = wi.getItem();
|
||||
MockWorkflowItem wfItem = new MockWorkflowItem();
|
||||
wfItem.item = item;
|
||||
wfItem.collection = collection;
|
||||
assertThrows(IllegalArgumentException.class, () -> workspaceItemService.create(context, wfItem));
|
||||
context.restoreAuthSystemState();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.workflow;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.eperson.EPerson;
|
||||
|
||||
public class MockWorkflowItem implements WorkflowItem {
|
||||
public Integer id;
|
||||
public Item item;
|
||||
public Collection collection;
|
||||
public EPerson submitter;
|
||||
boolean hasMultipleFiles;
|
||||
boolean hasMultipleTitles;
|
||||
boolean isPublishedBefore;
|
||||
|
||||
public Integer getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public Collection getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public EPerson getSubmitter() {
|
||||
return submitter;
|
||||
}
|
||||
|
||||
public boolean hasMultipleFiles() {
|
||||
return hasMultipleFiles;
|
||||
}
|
||||
|
||||
public void setMultipleFiles(boolean b) {
|
||||
hasMultipleFiles = b;
|
||||
}
|
||||
|
||||
public boolean hasMultipleTitles() {
|
||||
return hasMultipleTitles;
|
||||
}
|
||||
|
||||
public void setMultipleTitles(boolean b) {
|
||||
hasMultipleTitles = b;
|
||||
}
|
||||
|
||||
public boolean isPublishedBefore() {
|
||||
return isPublishedBefore;
|
||||
}
|
||||
|
||||
public void setPublishedBefore(boolean b) {
|
||||
isPublishedBefore = b;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user