Implement tilted relationships to help improve performance

This commit is contained in:
April Herron
2021-01-27 09:41:38 -05:00
parent 12ffc78452
commit 06c39ad750
18 changed files with 159 additions and 50 deletions

View File

@@ -146,6 +146,14 @@ public class InitializeEntities {
copyToRight = Boolean.valueOf(copyToRightNode.getTextContent());
}
Node tiltedNode = eElement.getElementsByTagName("tilted").item(0);
RelationshipType.Tilted tilted;
if (tiltedNode == null) {
tilted = RelationshipType.Tilted.NONE;
} else {
tilted = RelationshipType.Tilted.valueOf(tiltedNode.getTextContent().toUpperCase());
}
NodeList leftCardinalityList = eElement.getElementsByTagName("leftCardinality");
NodeList rightCardinalityList = eElement.getElementsByTagName("rightCardinality");
@@ -170,7 +178,8 @@ public class InitializeEntities {
}
populateRelationshipType(context, leftType, rightType, leftwardType, rightwardType,
leftCardinalityMin, leftCardinalityMax,
rightCardinalityMin, rightCardinalityMax, copyToLeft, copyToRight);
rightCardinalityMin, rightCardinalityMax, copyToLeft, copyToRight,
tilted);
}
@@ -190,7 +199,7 @@ public class InitializeEntities {
private void populateRelationshipType(Context context, String leftType, String rightType, String leftwardType,
String rightwardType, String leftCardinalityMin, String leftCardinalityMax,
String rightCardinalityMin, String rightCardinalityMax,
Boolean copyToLeft, Boolean copyToRight)
Boolean copyToLeft, Boolean copyToRight, RelationshipType.Tilted tilted)
throws SQLException, AuthorizeException {
EntityType leftEntityType = entityTypeService.findByEntityType(context,leftType);
@@ -231,10 +240,11 @@ public class InitializeEntities {
relationshipTypeService.create(context, leftEntityType, rightEntityType, leftwardType, rightwardType,
leftCardinalityMinInteger, leftCardinalityMaxInteger,
rightCardinalityMinInteger, rightCardinalityMaxInteger,
copyToLeft, copyToRight);
copyToLeft, copyToRight, tilted);
} else {
relationshipType.setCopyToLeft(copyToLeft);
relationshipType.setCopyToRight(copyToRight);
relationshipType.setTilted(tilted);
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);

View File

@@ -44,7 +44,7 @@ public class EntityServiceImpl implements EntityService {
public Entity findByItemId(Context context, UUID itemId, Integer limit, Integer offset) throws SQLException {
Item item = itemService.find(context, itemId);
List<Relationship> relationshipList = relationshipService.findByItem(context, item, limit, offset);
List<Relationship> relationshipList = relationshipService.findByItem(context, item, limit, offset, true);
return new Entity(item, relationshipList);
}

View File

@@ -46,7 +46,7 @@ public class RelationshipMetadataServiceImpl implements RelationshipMetadataServ
try {
String entityType = getEntityTypeStringFromMetadata(item);
if (StringUtils.isNotBlank(entityType)) {
List<Relationship> relationships = relationshipService.findByItem(context, item);
List<Relationship> relationships = relationshipService.findByItem(context, item, -1, -1, true);
for (Relationship relationship : relationships) {
fullMetadataValueList
.addAll(findRelationshipMetadataValueForItemRelationship(context, item, entityType,

View File

@@ -268,15 +268,14 @@ public class RelationshipServiceImpl implements RelationshipService {
@Override
public List<Relationship> findByItem(Context context, Item item) throws SQLException {
return findByItem(context, item, -1, -1);
return findByItem(context, item, -1, -1, false);
}
@Override
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset)
throws SQLException {
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset,
boolean excludeTilted) throws SQLException {
List<Relationship> list = relationshipDAO.findByItem(context, item, limit, offset);
List<Relationship> list = relationshipDAO.findByItem(context, item, limit, offset, excludeTilted);
list.sort((o1, o2) -> {
int relationshipType = o1.getRelationshipType().getLeftwardType()

View File

@@ -113,6 +113,13 @@ public class RelationshipType implements ReloadableEntity<Integer> {
*/
@Column(name = "copy_to_right", nullable = false)
private boolean copyToRight;
/**
* The value indicating whether the relationship has more relationships on the right/left/neither.
*/
@Column(name = "tilted")
private Tilted tilted;
/**
* Protected constructor, create object using:
* {@link org.dspace.content.service.RelationshipTypeService#create(Context)} }
@@ -287,6 +294,26 @@ public class RelationshipType implements ReloadableEntity<Integer> {
this.copyToRight = copyToRight;
}
/**
* Generic getter for tilted
* @return the tilted value of this RelationshipType
*/
public Tilted getTilted() {
return tilted;
}
/**
* Generic setter for tilted
* @param tilted The tilted to be set on this RelationshipType
*/
public void setTilted(Tilted tilted) {
this.tilted = tilted;
}
public enum Tilted {
NONE, LEFT, RIGHT;
}
/**
* Standard getter for the ID of this RelationshipType
* @return The ID of this RelationshipType

View File

@@ -121,7 +121,8 @@ public class RelationshipTypeServiceImpl implements RelationshipTypeService {
public RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
Integer rightCardinalityMaxInteger, Boolean copyToLeft, Boolean copyToRight)
Integer rightCardinalityMaxInteger, Boolean copyToLeft, Boolean copyToRight,
RelationshipType.Tilted tilted)
throws SQLException, AuthorizeException {
RelationshipType relationshipType = new RelationshipType();
relationshipType.setLeftType(leftEntityType);
@@ -130,6 +131,7 @@ public class RelationshipTypeServiceImpl implements RelationshipTypeService {
relationshipType.setRightwardType(rightwardType);
relationshipType.setCopyToLeft(copyToLeft);
relationshipType.setCopyToRight(copyToRight);
relationshipType.setTilted(tilted);
relationshipType.setLeftMinCardinality(leftCardinalityMinInteger);
relationshipType.setLeftMaxCardinality(leftCardinalityMaxInteger);
relationshipType.setRightMinCardinality(rightCardinalityMinInteger);

View File

@@ -30,11 +30,12 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
* @param context The relevant DSpace context
* @param item The item that should be either a leftItem or a rightItem of all
* the Relationship objects in the returned list
* @param excludeTilted If true, excludes tilted relationships
* @return The list of Relationship objects that contain either a left or a
* right item that is equal to the given item
* @throws SQLException If something goes wrong
*/
List<Relationship> findByItem(Context context, Item item) throws SQLException;
List<Relationship> findByItem(Context context, Item item, boolean excludeTilted) throws SQLException;
/**
* This method returns a list of Relationship objects that have the given Item object
@@ -44,11 +45,13 @@ public interface RelationshipDAO extends GenericDAO<Relationship> {
* the Relationship objects in the returned list
* @param limit paging limit
* @param offset paging offset
* @param excludeTilted If true, excludes tilted relationships
* @return The list of Relationship objects that contain either a left or a
* right item that is equal to the given item
* @throws SQLException If something goes wrong
*/
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset) throws SQLException;
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset, boolean excludeTilted)
throws SQLException;
/**
* This method returns the next leftplace integer to use for a relationship with this item as the leftItem

View File

@@ -17,6 +17,7 @@ import javax.persistence.criteria.Root;
import org.dspace.content.Item;
import org.dspace.content.Relationship;
import org.dspace.content.RelationshipType;
import org.dspace.content.RelationshipType_;
import org.dspace.content.Relationship_;
import org.dspace.content.dao.RelationshipDAO;
import org.dspace.content.factory.ContentServiceFactory;
@@ -27,22 +28,42 @@ import org.dspace.core.Context;
public class RelationshipDAOImpl extends AbstractHibernateDAO<Relationship> implements RelationshipDAO {
@Override
public List<Relationship> findByItem(Context context, Item item) throws SQLException {
return findByItem(context, item, -1, -1);
public List<Relationship> findByItem(Context context, Item item, boolean excludeTilted) throws SQLException {
return findByItem(context, item, -1, -1, excludeTilted);
}
@Override
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset)
throws SQLException {
public List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset,
boolean excludeTilted) throws SQLException {
CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context);
CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Relationship.class);
Root<Relationship> relationshipRoot = criteriaQuery.from(Relationship.class);
criteriaQuery.select(relationshipRoot);
if (excludeTilted) {
criteriaQuery
.where(criteriaBuilder.or(
criteriaBuilder.and(
criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
criteriaBuilder.or(
criteriaBuilder.isNull(relationshipRoot.get(Relationship_.relationshipType)
.get(RelationshipType_.tilted)),
criteriaBuilder.notEqual(relationshipRoot
.get(Relationship_.relationshipType)
.get(RelationshipType_.tilted), RelationshipType.Tilted.RIGHT))),
criteriaBuilder.and(
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item),
criteriaBuilder.or(
criteriaBuilder.isNull(relationshipRoot.get(Relationship_.relationshipType)
.get(RelationshipType_.tilted)),
criteriaBuilder.notEqual(relationshipRoot
.get(Relationship_.relationshipType)
.get(RelationshipType_.tilted), RelationshipType.Tilted.LEFT)))));
} else {
criteriaQuery
.where(criteriaBuilder.or(criteriaBuilder.equal(relationshipRoot.get(Relationship_.leftItem), item),
criteriaBuilder.equal(relationshipRoot.get(Relationship_.rightItem), item)));
}
return list(context, criteriaQuery, false, Relationship.class, limit, offset);
}

View File

@@ -36,13 +36,17 @@ public interface RelationshipService extends DSpaceCRUDService<Relationship> {
* Retrieves the list of Relationships currently in the system for which the given Item is either
* a leftItem or a rightItem object
* @param context The relevant DSpace context
* @param item The Item that has to be the left or right item for the relationship to be included in the list
* @param item The Item that has to be the left or right item for the relationship to be
* included in the list
* @param limit paging limit
* @param offset paging offset
* @return The list of relationships for which each relationship adheres to the above listed constraint
* @param excludeTilted If true, excludes tilted relationships
* @return The list of relationships for which each relationship adheres to the above
* listed constraint
* @throws SQLException If something goes wrong
*/
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset) throws SQLException;
List<Relationship> findByItem(Context context, Item item, Integer limit, Integer offset, boolean excludeTilted)
throws SQLException;
/**
* Retrieves the full list of relationships currently in the system

View File

@@ -174,6 +174,7 @@ public interface RelationshipTypeService extends DSpaceCRUDService<RelationshipT
RelationshipType create(Context context, EntityType leftEntityType, EntityType rightEntityType,
String leftwardType, String rightwardType, Integer leftCardinalityMinInteger,
Integer leftCardinalityMaxInteger, Integer rightCardinalityMinInteger,
Integer rightCardinalityMaxInteger, Boolean copyToLeft, Boolean copyToRight)
Integer rightCardinalityMaxInteger, Boolean copyToLeft, Boolean copyToRight,
RelationshipType.Tilted tilted)
throws SQLException, AuthorizeException;
}

View File

@@ -0,0 +1,13 @@
--
-- 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/
--
-----------------------------------------------------------------------------------
-- Create columns copy_left and copy_right for RelationshipType
-----------------------------------------------------------------------------------
ALTER TABLE relationship_type ADD tilted INTEGER;

View File

@@ -0,0 +1,13 @@
--
-- 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/
--
-----------------------------------------------------------------------------------
-- Create columns copy_left and copy_right for RelationshipType
-----------------------------------------------------------------------------------
ALTER TABLE relationship_type ADD tilted INTEGER;

View File

@@ -0,0 +1,13 @@
--
-- 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/
--
-----------------------------------------------------------------------------------
-- Create columns copy_left and copy_right for RelationshipType
-----------------------------------------------------------------------------------
ALTER TABLE relationship_type ADD tilted INTEGER;

View File

@@ -2,13 +2,14 @@
<!ELEMENT relationships (type)*>
<!ELEMENT type (leftType|rightType|leftwardType|rightwardType|leftCardinality|rightCardinality|copyToLeft|copyToRight)*>
<!ELEMENT type (leftType|rightType|leftwardType|rightwardType|leftCardinality|rightCardinality|copyToLeft|copyToRight|tilted)*>
<!ELEMENT leftType (#PCDATA)>
<!ELEMENT rightType (#PCDATA)>
<!ELEMENT leftwardType (#PCDATA)>
<!ELEMENT rightwardType (#PCDATA)>
<!ELEMENT copyToLeft (#PCDATA)>
<!ELEMENT copyToRight (#PCDATA)>
<!ELEMENT tilted (#PCDATA)>
<!ELEMENT leftCardinality (min|max)*>
<!ELEMENT min (#PCDATA)>
<!ELEMENT rightCardinality (min|max)*>

View File

@@ -110,10 +110,10 @@ public class RelationshipServiceImplTest {
relationshipTest.add(getRelationship(cindy, hank, hasFather,0,0));
relationshipTest.add(getRelationship(fred, cindy, hasMother,0,0));
relationshipTest.add(getRelationship(bob, cindy, hasMother,1,0));
when(relationshipService.findByItem(context, cindy, -1, -1)).thenReturn(relationshipTest);
when(relationshipService.findByItem(context, cindy, -1, -1, false)).thenReturn(relationshipTest);
// Mock the state of objects utilized in findByItem() to meet the success criteria of the invocation
when(relationshipDAO.findByItem(context, cindy, -1, -1)).thenReturn(relationshipTest);
when(relationshipDAO.findByItem(context, cindy, -1, -1, false)).thenReturn(relationshipTest);
List<Relationship> results = relationshipService.findByItem(context, cindy);
assertEquals("TestFindByItem 0", relationshipTest, results);

View File

@@ -134,7 +134,8 @@ public class RelationshipDAOImplTest extends AbstractIntegrationTest {
*/
@Test
public void testFindByItem() throws Exception {
assertEquals("TestFindByItem 0", relationshipsList, relationshipService.findByItem(context, itemOne, -1, -1));
assertEquals("TestFindByItem 0", relationshipsList, relationshipService.findByItem(context, itemOne,
-1, -1, false));
}
/**

View File

@@ -55,7 +55,7 @@ public class ItemRelationshipLinkRepository extends AbstractDSpaceRestRepository
int total = relationshipService.countByItem(context, item);
Pageable pageable = utils.getPageable(optionalPageable);
List<Relationship> relationships = relationshipService.findByItem(context, item,
pageable.getPageSize(), Math.toIntExact(pageable.getOffset()));
pageable.getPageSize(), Math.toIntExact(pageable.getOffset()), true);
return converter.toRestPage(relationships, pageable, total, projection);
} catch (SQLException e) {
throw new RuntimeException(e);

View File

@@ -2,13 +2,14 @@
<!ELEMENT relationships (type)*>
<!ELEMENT type (leftType|rightType|leftwardType|rightwardType|leftCardinality|rightCardinality|copyToLeft|copyToRight)*>
<!ELEMENT type (leftType|rightType|leftwardType|rightwardType|leftCardinality|rightCardinality|copyToLeft|copyToRight|tilted)*>
<!ELEMENT leftType (#PCDATA)>
<!ELEMENT rightType (#PCDATA)>
<!ELEMENT leftwardType (#PCDATA)>
<!ELEMENT rightwardType (#PCDATA)>
<!ELEMENT copyToLeft (#PCDATA)>
<!ELEMENT copyToRight (#PCDATA)>
<!ELEMENT tilted (#PCDATA)>
<!ELEMENT leftCardinality (min|max)*>
<!ELEMENT min (#PCDATA)>
<!ELEMENT rightCardinality (min|max)*>