[ACS-10041] Repository - CPU spikes and OOM errors with SQL Server 2019 (#3588)

This commit is contained in:
cezary-witkowski
2025-09-23 14:10:29 +02:00
committed by GitHub
parent 1251081a69
commit ef034e596b
5 changed files with 6538 additions and 6437 deletions

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -36,8 +36,7 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.namespace.QName;
/**
* Class holding properties associated with the <b>sys:referenceable</b> aspect.
* This aspect is common enough to warrant direct inclusion on the <b>Node</b> entity.
* Class holding properties associated with the <b>sys:referenceable</b> aspect. This aspect is common enough to warrant direct inclusion on the <b>Node</b> entity.
*
* @author Derek Hulley
* @since 3.4
@@ -55,7 +54,7 @@ public class ReferenceablePropertiesEntity
}
/**
* @return Returns <tt>true</tt> if the property belongs to the <b>sys:referenceable</b> aspect
* @return Returns <tt>true</tt> if the property belongs to the <b>sys:referenceable</b> aspect
*/
public static boolean isReferenceableProperty(QName qname)
{
@@ -87,10 +86,8 @@ public class ReferenceablePropertiesEntity
/**
* Adds all {@link ContentModel#ASPECT_REFERENCEABLE referencable} properties.
*/
public static void addReferenceableProperties(Node node, Map<QName, Serializable> properties)
public static void addReferenceableProperties(Long nodeId, NodeRef nodeRef, Map<QName, Serializable> properties)
{
Long nodeId = node.getId();
NodeRef nodeRef = node.getNodeRef();
properties.put(ContentModel.PROP_STORE_PROTOCOL, nodeRef.getStoreRef().getProtocol());
properties.put(ContentModel.PROP_STORE_IDENTIFIER, nodeRef.getStoreRef().getIdentifier());
properties.put(ContentModel.PROP_NODE_UUID, nodeRef.getId());

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -28,8 +28,10 @@ package org.alfresco.repo.node.getchildren;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.domain.node.NodeEntity;
import org.alfresco.repo.domain.node.AuditablePropertiesEntity;
import org.alfresco.repo.domain.node.NodePropertyEntity;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* Filterable/Sortable Node Entity
@@ -42,12 +44,17 @@ import org.alfresco.repo.domain.node.NodePropertyEntity;
public class FilterSortNodeEntity
{
private Long id; // node id
private String nodeUuid;
private Long typeQNameId;
private NodeEntity node;
private AuditablePropertiesEntity auditablePropertiesEntity;
private NodePropertyEntity prop1;
private NodePropertyEntity prop2;
private NodePropertyEntity prop3;
private String storeProtocol;
private String storeIdentifier;
// Supplemental query-related parameters
private Long parentNodeId;
private Long prop1qnameId;
@@ -80,6 +87,26 @@ public class FilterSortNodeEntity
this.id = id;
}
public String getNodeUuid()
{
return nodeUuid;
}
public void setNodeUuid(String nodeUuid)
{
this.nodeUuid = nodeUuid;
}
public Long getTypeQNameId()
{
return typeQNameId;
}
public void setTypeQNameId(Long typeQNameId)
{
this.typeQNameId = typeQNameId;
}
public String getPattern()
{
return pattern;
@@ -93,22 +120,21 @@ public class FilterSortNodeEntity
do
{
idx = s.indexOf(escapeChar, offset);
if(idx != -1)
if (idx != -1)
{
sb.append(s.substring(offset, idx));
sb.append("\\");
sb.append(escapeChar);
offset = idx + 1;
}
}
while(idx != -1);
} while (idx != -1);
sb.append(s.substring(offset));
return sb.toString();
}
public void setPattern(String pattern)
{
if(pattern != null)
if (pattern != null)
{
// escape the '%' character with '\' (standard SQL escape character)
pattern = escape(pattern, '%');
@@ -137,6 +163,16 @@ public class FilterSortNodeEntity
this.namePropertyQNameId = namePropertyQNameId;
}
public AuditablePropertiesEntity getAuditablePropertiesEntity()
{
return auditablePropertiesEntity;
}
public void setAuditablePropertiesEntity(AuditablePropertiesEntity auditablePropertiesEntity)
{
this.auditablePropertiesEntity = auditablePropertiesEntity;
}
public NodePropertyEntity getProp1()
{
return prop1;
@@ -167,14 +203,24 @@ public class FilterSortNodeEntity
this.prop3 = prop3;
}
public NodeEntity getNode()
public String getStoreProtocol()
{
return node;
return storeProtocol;
}
public void setNode(NodeEntity childNode)
public void setStoreProtocol(String storeProtocol)
{
this.node = childNode;
this.storeProtocol = storeProtocol;
}
public String getStoreIdentifier()
{
return storeIdentifier;
}
public void setStoreIdentifier(String storeIdentifier)
{
this.storeIdentifier = storeIdentifier;
}
// Supplemental query-related parameters
@@ -258,4 +304,9 @@ public class FilterSortNodeEntity
{
this.isPrimary = isPrimary;
}
public NodeRef createNodeRef()
{
return new NodeRef(new StoreRef(storeProtocol, storeIdentifier), nodeUuid);
}
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Repository
* %%
* Copyright (C) 2005 - 2016 Alfresco Software Limited
* Copyright (C) 2005 - 2025 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* If the software was purchased under a paid Alfresco license, the terms of
@@ -38,13 +38,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.query.CannedQueryParameters;
import org.alfresco.query.CannedQuerySortDetails;
import org.alfresco.query.CannedQuerySortDetails.SortOrder;
import org.alfresco.repo.domain.node.AuditablePropertiesEntity;
import org.alfresco.repo.domain.node.Node;
import org.alfresco.repo.domain.node.NodeDAO;
import org.alfresco.repo.domain.node.NodeEntity;
import org.alfresco.repo.domain.node.NodePropertyEntity;
@@ -69,15 +72,11 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.util.AlfrescoCollator;
import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* GetChildren canned query
*
* To get paged list of children of a parent node filtered by child type.
* Also optionally filtered and/or sorted by one or more properties (up to three).
* To get paged list of children of a parent node filtered by child type. Also optionally filtered and/or sorted by one or more properties (up to three).
*
* @author janv
* @since 4.0
@@ -100,7 +99,6 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
public static final QName FILTER_QNAME_NODE_IS_PRIMARY = QName.createQName("", "IS_PRIMARY");
private NodeDAO nodeDAO;
private QNameDAO qnameDAO;
private CannedQueryDAO cannedQueryDAO;
@@ -135,8 +133,8 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
}
// TODO refactor (only apply post query if sorted - as above)
GetChildrenCannedQueryParams paramBean = (GetChildrenCannedQueryParams)params.getParameterBean();
if ((paramBean.getFilterProps()!= null) && (paramBean.getFilterProps().size() > 0))
GetChildrenCannedQueryParams paramBean = (GetChildrenCannedQueryParams) params.getParameterBean();
if ((paramBean.getFilterProps() != null) && (paramBean.getFilterProps().size() > 0))
{
applyPostQueryPermissions = true;
}
@@ -163,7 +161,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
Long start = (logger.isDebugEnabled() ? System.currentTimeMillis() : null);
// Get parameters
GetChildrenCannedQueryParams paramBean = (GetChildrenCannedQueryParams)parameters.getParameterBean();
GetChildrenCannedQueryParams paramBean = (GetChildrenCannedQueryParams) parameters.getParameterBean();
// Get parent node
NodeRef parentRef = paramBean.getParentRef();
@@ -192,8 +190,8 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
// Get sort details
CannedQuerySortDetails sortDetails = parameters.getSortDetails();
@SuppressWarnings({ "unchecked", "rawtypes" })
final List<Pair<QName, SortOrder>> sortPairs = (List)sortDetails.getSortPairs();
@SuppressWarnings({"unchecked", "rawtypes"})
final List<Pair<QName, SortOrder>> sortPairs = (List) sortDetails.getSortPairs();
if (filterProps.size() > 0)
{
@@ -203,9 +201,9 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
for (FilterProp filter : filterProps)
{
if ((filter instanceof FilterPropBoolean) &&
((FilterPropBoolean)filter).getPropName().equals(FILTER_QNAME_NODE_IS_PRIMARY))
((FilterPropBoolean) filter).getPropName().equals(FILTER_QNAME_NODE_IS_PRIMARY))
{
isPrimary = ((FilterPropBoolean)filter).getPropVal();
isPrimary = ((FilterPropBoolean) filter).getPropVal();
break;
}
idx++;
@@ -223,17 +221,17 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
for (Pair<QName, SortOrder> sort : sortPairs)
{
QName sortQName = sort.getFirst();
if(! sortFilterProps.contains(sortQName))
if (!sortFilterProps.contains(sortQName))
{
sortFilterProps.add(sortQName);
sortFilterProps.add(sortQName);
}
}
for (FilterProp filter : filterProps)
{
QName filterQName = filter.getPropName();
if(! sortFilterProps.contains(filterQName))
if (!sortFilterProps.contains(filterQName))
{
sortFilterProps.add(filterQName);
sortFilterProps.add(filterQName);
}
}
@@ -241,109 +239,108 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (filterSortPropCnt > MAX_FILTER_SORT_PROPS)
{
throw new AlfrescoRuntimeException("GetChildren: exceeded maximum number filter/sort properties: (max="+MAX_FILTER_SORT_PROPS+", actual="+filterSortPropCnt);
throw new AlfrescoRuntimeException("GetChildren: exceeded maximum number filter/sort properties: (max=" + MAX_FILTER_SORT_PROPS + ", actual=" + filterSortPropCnt);
}
filterSortPropCnt = setFilterSortParams(sortFilterProps, params);
List<NodeRef> result = new ArrayList<>(0);
try
{
if ((childNodeTypeQNames != null) && (childNodeTypeQNames.size() > 0))
{
// Set child node type qnames (additional filter - performed by DB query)
Set<Long> childNodeTypeQNameIds = qnameDAO.convertQNamesToIds(childNodeTypeQNames, false);
if (childNodeTypeQNameIds.size() > 0)
{
params.setChildNodeTypeQNameIds(new ArrayList<Long>(childNodeTypeQNameIds));
}
else
{
// short-circuit - return no results - given node type qname(s) do not exist
return result;
}
}
if ((childNodeTypeQNames != null) && (childNodeTypeQNames.size() > 0))
{
// Set child node type qnames (additional filter - performed by DB query)
Set<Long> childNodeTypeQNameIds = qnameDAO.convertQNamesToIds(childNodeTypeQNames, false);
if (childNodeTypeQNameIds.size() > 0)
{
params.setChildNodeTypeQNameIds(new ArrayList<Long>(childNodeTypeQNameIds));
}
else
{
// short-circuit - return no results - given node type qname(s) do not exist
return result;
}
}
if ((assocTypeQNames != null) && (assocTypeQNames.size() > 0))
{
// Set assoc type qnames (additional filter - performed by DB query)
Set<Long> assocTypeQNameIds = qnameDAO.convertQNamesToIds(assocTypeQNames, false);
if (assocTypeQNameIds.size() > 0)
{
params.setAssocTypeQNameIds(assocTypeQNameIds);
}
else
{
// short-circuit - return no results - given assoc type qname(s) do not exist
return result;
}
}
if ((assocTypeQNames != null) && (assocTypeQNames.size() > 0))
{
// Set assoc type qnames (additional filter - performed by DB query)
Set<Long> assocTypeQNameIds = qnameDAO.convertQNamesToIds(assocTypeQNames, false);
if (assocTypeQNameIds.size() > 0)
{
params.setAssocTypeQNameIds(assocTypeQNameIds);
}
else
{
// short-circuit - return no results - given assoc type qname(s) do not exist
return result;
}
}
if (pattern != null)
{
// TODO, check that we should be tied to the content model in this way. Perhaps a configurable property
// name against which compare the pattern?
Pair<Long, QName> nameQName = qnameDAO.getQName(ContentModel.PROP_NAME);
if(nameQName == null)
{
throw new AlfrescoRuntimeException("Unable to determine qname id of name property");
}
params.setNamePropertyQNameId(nameQName.getFirst());
params.setPattern(pattern);
}
if (pattern != null)
{
// TODO, check that we should be tied to the content model in this way. Perhaps a configurable property
// name against which compare the pattern?
Pair<Long, QName> nameQName = qnameDAO.getQName(ContentModel.PROP_NAME);
if (nameQName == null)
{
throw new AlfrescoRuntimeException("Unable to determine qname id of name property");
}
params.setNamePropertyQNameId(nameQName.getFirst());
params.setPattern(pattern);
}
if (filterSortPropCnt > 0)
{
// filtered and/or sorted - note: permissions will be applied post query
final List<FilterSortNode> children = new ArrayList<FilterSortNode>(100);
final FilterSortChildQueryCallback c = getFilterSortChildQuery(children, filterProps, paramBean);
FilterSortResultHandler resultHandler = new FilterSortResultHandler(c);
cannedQueryDAO.executeQuery(QUERY_NAMESPACE, QUERY_SELECT_GET_CHILDREN_WITH_PROPS, params, 0, Integer.MAX_VALUE, resultHandler);
resultHandler.done();
if (filterSortPropCnt > 0)
{
// filtered and/or sorted - note: permissions will be applied post query
final List<FilterSortNode> children = new ArrayList<FilterSortNode>(100);
final FilterSortChildQueryCallback c = getFilterSortChildQuery(children, filterProps, paramBean);
FilterSortResultHandler resultHandler = new FilterSortResultHandler(c);
cannedQueryDAO.executeQuery(QUERY_NAMESPACE, QUERY_SELECT_GET_CHILDREN_WITH_PROPS, params, 0, Integer.MAX_VALUE, resultHandler);
resultHandler.done();
if (sortPairs.size() > 0)
{
Long startSort = (logger.isDebugEnabled() ? System.currentTimeMillis() : null);
if (sortPairs.size() > 0)
{
Long startSort = (logger.isDebugEnabled() ? System.currentTimeMillis() : null);
// sort
Collections.sort(children, new PropComparatorAsc(sortPairs));
// sort
Collections.sort(children, new PropComparatorAsc(sortPairs));
if (startSort != null)
{
logger.debug("Post-query sort: "+children.size()+" in "+(System.currentTimeMillis()-startSort)+" msecs");
}
}
if (startSort != null)
{
logger.debug("Post-query sort: " + children.size() + " in " + (System.currentTimeMillis() - startSort) + " msecs");
}
}
result = new ArrayList<NodeRef>(children.size());
for (FilterSortNode child : children)
{
result.add(tenantService.getBaseName(child.getNodeRef()));
}
}
else
{
// unsorted (apart from any implicit order) - note: permissions are applied during result handling to allow early cutoff
result = new ArrayList<NodeRef>(children.size());
for (FilterSortNode child : children)
{
result.add(tenantService.getBaseName(child.getNodeRef()));
}
}
else
{
// unsorted (apart from any implicit order) - note: permissions are applied during result handling to allow early cutoff
final int requestedCount = parameters.getResultsRequired();
final int requestedCount = parameters.getResultsRequired();
final List<NodeRef> rawResult = new ArrayList<NodeRef>(Math.min(1000, requestedCount));
UnsortedChildQueryCallback callback = getUnsortedChildQueryCallback(rawResult, requestedCount, paramBean);
UnsortedResultHandler resultHandler = new UnsortedResultHandler(callback);
cannedQueryDAO.executeQuery(QUERY_NAMESPACE, QUERY_SELECT_GET_CHILDREN_WITHOUT_PROPS, params, 0, Integer.MAX_VALUE, resultHandler);
resultHandler.done();
final List<NodeRef> rawResult = new ArrayList<NodeRef>(Math.min(1000, requestedCount));
UnsortedChildQueryCallback callback = getUnsortedChildQueryCallback(rawResult, requestedCount, paramBean);
UnsortedResultHandler resultHandler = new UnsortedResultHandler(callback);
cannedQueryDAO.executeQuery(QUERY_NAMESPACE, QUERY_SELECT_GET_CHILDREN_WITHOUT_PROPS, params, 0, Integer.MAX_VALUE, resultHandler);
resultHandler.done();
// permissions have been applied
result = PermissionCheckedValueMixin.create(rawResult);
}
// permissions have been applied
result = PermissionCheckedValueMixin.create(rawResult);
}
}
finally
{
if (start != null)
{
logger.debug("Base query "+(filterSortPropCnt > 0 ? "(sort=y, perms=n)" : "(sort=n, perms=y)")+": "+result.size()+" in "+(System.currentTimeMillis()-start)+" msecs");
}
if (start != null)
{
logger.debug("Base query " + (filterSortPropCnt > 0 ? "(sort=y, perms=n)" : "(sort=n, perms=y)") + ": " + result.size() + " in " + (System.currentTimeMillis() - start) + " msecs");
}
}
return result;
@@ -385,14 +382,14 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
else
{
// belts and braces
throw new AlfrescoRuntimeException("GetChildren: unexpected - cannot set sort parameter: "+cnt);
throw new AlfrescoRuntimeException("GetChildren: unexpected - cannot set sort parameter: " + cnt);
}
propCnt++;
}
else
{
logger.warn("Skipping filter/sort param - cannot find: "+filterSortProp);
logger.warn("Skipping filter/sort param - cannot find: " + filterSortProp);
break;
}
}
@@ -443,7 +440,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
Object pv1 = null;
Object pv2 = null;
QName sortPropQName = (QName)sortProps.get(0).getFirst();
QName sortPropQName = (QName) sortProps.get(0).getFirst();
boolean sortAscending = (sortProps.get(0).getSecond() == SortOrder.ASCENDING);
FilterSortNode node1 = node1In;
@@ -462,7 +459,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (pv1 == null)
{
if(pv2 == null && sortProps.size() > 1)
if (pv2 == null && sortProps.size() > 1)
{
return compareImpl(node1In, node2In, sortProps.subList(1, sortProps.size()));
}
@@ -478,32 +475,32 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (pv1 instanceof String)
{
result = collator.compare((String)pv1, (String)pv2); // TODO use collation keys (re: performance)
result = collator.compare((String) pv1, (String) pv2); // TODO use collation keys (re: performance)
}
else if (pv1 instanceof Date)
{
result = (((Date)pv1).compareTo((Date)pv2));
result = (((Date) pv1).compareTo((Date) pv2));
}
else if (pv1 instanceof Long)
{
result = (((Long)pv1).compareTo((Long)pv2));
result = (((Long) pv1).compareTo((Long) pv2));
}
else if (pv1 instanceof Integer)
{
result = (((Integer)pv1).compareTo((Integer)pv2));
result = (((Integer) pv1).compareTo((Integer) pv2));
}
else if (pv1 instanceof QName)
{
result = (((QName)pv1).compareTo((QName)pv2));
result = (((QName) pv1).compareTo((QName) pv2));
}
else if (pv1 instanceof Boolean)
{
result = (((Boolean)pv1).compareTo((Boolean)pv2));
result = (((Boolean) pv1).compareTo((Boolean) pv2));
}
else
{
// TODO other comparisons
throw new RuntimeException("Unsupported sort type: "+pv1.getClass().getName());
throw new RuntimeException("Unsupported sort type: " + pv1.getClass().getName());
}
if ((result == 0) && (sortProps.size() > 1))
@@ -555,68 +552,68 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
{
if ((filterProp instanceof FilterPropString) && (propVal instanceof String))
{
String val = (String)propVal;
String filter = (String)filterProp.getPropVal();
String val = (String) propVal;
String filter = (String) filterProp.getPropVal();
switch ((FilterTypeString)filterProp.getFilterType())
switch ((FilterTypeString) filterProp.getFilterType())
{
case STARTSWITH:
if (val.startsWith(filter))
{
return true;
}
case STARTSWITH:
if (val.startsWith(filter))
{
return true;
}
break;
case STARTSWITH_IGNORECASE:
if (val.toLowerCase().startsWith(filter.toLowerCase()))
{
return true;
}
break;
case EQUALS:
if (val.equals(filter))
{
return true;
}
case STARTSWITH_IGNORECASE:
if (val.toLowerCase().startsWith(filter.toLowerCase()))
{
return true;
}
break;
case EQUALS_IGNORECASE:
if (val.equalsIgnoreCase(filter))
{
return true;
}
break;
case ENDSWITH:
if (val.endsWith(filter))
{
return true;
}
break;
case ENDSWITH_IGNORECASE:
if (val.toLowerCase().endsWith(filter.toLowerCase()))
{
return true;
}
break;
case MATCHES:
if (val.matches(filter))
{
return true;
}
break;
case MATCHES_IGNORECASE:
if (val.toLowerCase().matches(filter.toLowerCase()))
{
return true;
}
break;
default:
case EQUALS:
if (val.equals(filter))
{
return true;
}
break;
case EQUALS_IGNORECASE:
if (val.equalsIgnoreCase(filter))
{
return true;
}
break;
case ENDSWITH:
if (val.endsWith(filter))
{
return true;
}
break;
case ENDSWITH_IGNORECASE:
if (val.toLowerCase().endsWith(filter.toLowerCase()))
{
return true;
}
break;
case MATCHES:
if (val.matches(filter))
{
return true;
}
break;
case MATCHES_IGNORECASE:
if (val.toLowerCase().matches(filter.toLowerCase()))
{
return true;
}
break;
default:
}
}
}
if ((filterProp instanceof FilterPropBoolean) && (propVal instanceof Boolean))
{
Boolean val = (Boolean)propVal;
Boolean filter = (Boolean)filterProp.getPropVal();
Boolean val = (Boolean) propVal;
Boolean filter = (Boolean) filterProp.getPropVal();
return (val == filter);
}
@@ -649,7 +646,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (start != null)
{
logger.debug("Post-query perms: "+ret.size()+" in "+(System.currentTimeMillis()-start)+" msecs");
logger.debug("Post-query perms: " + ret.size() + " in " + (System.currentTimeMillis() - start) + " msecs");
}
return ret;
@@ -663,7 +660,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (start != null)
{
logger.trace("Pre-load: "+nodeRefs.size()+" in "+(System.currentTimeMillis()-start)+" msecs");
logger.trace("Pre-load: " + nodeRefs.size() + " in " + (System.currentTimeMillis() - start) + " msecs");
}
}
@@ -697,7 +694,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
@Override
public boolean handle(FilterSortNode node)
{
if(include(node))
if (include(node))
{
children.add(node);
}
@@ -709,7 +706,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
protected boolean include(FilterSortNode node)
{
// filter, if needed
return(!applyFilter || includeFilter(node.getPropVals(), filterProps)) && includeAspects(node.getNodeRef(), inclusiveAspects, exclusiveAspects);
return (!applyFilter || includeFilter(node.getPropVals(), filterProps)) && includeAspects(node.getNodeRef(), inclusiveAspects, exclusiveAspects);
}
}
@@ -731,7 +728,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
@Override
public boolean handle(NodeRef nodeRef)
{
if(include(nodeRef))
if (include(nodeRef))
{
rawResult.add(tenantService.getBaseName(nodeRef));
}
@@ -777,7 +774,8 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (results.size() >= BATCH_SIZE)
{
// batch
preloadFilterSort();
preloadNodes();
filterSort();
}
results.add(result);
@@ -790,24 +788,27 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
if (results.size() >= 0)
{
// finish batch
preloadFilterSort();
preloadNodes();
filterSort();
}
}
private void preloadFilterSort()
private void preloadNodes()
{
List<NodeRef> nodeRefs = new ArrayList<>(results.size());
List<NodeRef> nodeRefs = new ArrayList<>(results.size());
for (FilterSortNodeEntity result : results)
{
nodeRefs.add(result.getNode().getNodeRef());
nodeRefs.add(result.createNodeRef());
}
preload(nodeRefs);
}
private void filterSort()
{
for (FilterSortNodeEntity result : results)
{
Node node = result.getNode();
NodeRef nodeRef = node.getNodeRef();
NodeRef nodeRef = result.createNodeRef();
Map<NodePropertyKey, NodePropertyValue> propertyValues = new HashMap<NodePropertyKey, NodePropertyValue>(3);
@@ -832,7 +833,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
Map<QName, Serializable> propVals = nodePropertyHelper.convertToPublicProperties(propertyValues);
// Add referenceable / spoofed properties (including spoofed name if null)
ReferenceablePropertiesEntity.addReferenceableProperties(node, propVals);
ReferenceablePropertiesEntity.addReferenceableProperties(result.getId(), nodeRef, propVals);
// special cases
@@ -841,12 +842,12 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
{
if (entry.getValue() instanceof MLText)
{
propVals.put(entry.getKey(), DefaultTypeConverter.INSTANCE.convert(String.class, (MLText)entry.getValue()));
propVals.put(entry.getKey(), DefaultTypeConverter.INSTANCE.convert(String.class, (MLText) entry.getValue()));
}
}
// ContentData (eg. cm:content.size, cm:content.mimetype)
ContentData contentData = (ContentData)propVals.get(ContentModel.PROP_CONTENT);
ContentData contentData = (ContentData) propVals.get(ContentModel.PROP_CONTENT);
if (contentData != null)
{
propVals.put(SORT_QNAME_CONTENT_SIZE, contentData.getSize());
@@ -854,7 +855,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
}
// Auditable props (eg. cm:creator, cm:created, cm:modifier, cm:modified, ...)
AuditablePropertiesEntity auditableProps = node.getAuditableProperties();
AuditablePropertiesEntity auditableProps = result.getAuditablePropertiesEntity();
if (auditableProps != null)
{
for (Map.Entry<QName, Serializable> entry : auditableProps.getAuditableProperties().entrySet())
@@ -864,7 +865,7 @@ public class GetChildrenCannedQuery extends AbstractCannedQueryPermissions<NodeR
}
// Node type
Long nodeTypeQNameId = node.getTypeQNameId();
Long nodeTypeQNameId = result.getTypeQNameId();
if (nodeTypeQNameId != null)
{
Pair<Long, QName> pair = qnameDAO.getQName(nodeTypeQNameId);

View File

@@ -133,6 +133,14 @@
<resultMap id="result_FilterSortNode" type="FilterSortNode">
<id property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="nodeUuid" column="uuid" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="typeQNameId" column="type_qname_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="auditablePropertiesEntity.auditCreator" column="audit_creator" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditCreated" column="audit_created" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditModifier" column="audit_modifier" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditModified" column="audit_modified" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="auditablePropertiesEntity.auditAccessed" column="audit_accessed" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="prop1.nodeId" column="prop1_node_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="prop1.key.qnameId" column="prop1_qname_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
@@ -170,7 +178,8 @@
<result property="prop3.value.doubleValue" column="prop3_double_value" jdbcType="FLOAT" javaType="java.lang.Double"/>
<result property="prop3.value.stringValue" column="prop3_string_value" jdbcType="VARCHAR" javaType="java.lang.String"/>
<association property="node" resultMap="alfresco.node.result_Node"/>
<result property="storeProtocol" column="protocol" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="storeIdentifier" column="identifier" jdbcType="VARCHAR" javaType="java.lang.String"/>
</resultMap>
@@ -972,8 +981,8 @@
</select>
<!-- GetChildren - with explicit prop filtering and/or sorting -->
<select id="select_GetChildrenCannedQueryWithProps" parameterType="FilterSortNode" resultMap="result_FilterSortNode">
select
<select id="select_GetChildrenCannedQueryWithProps" parameterType="FilterSortNode" resultMap="result_FilterSortNode" flushCache="true">
select distinct
childNode.id as id,
childNode.version as version,
childStore.id as store_id,
@@ -989,7 +998,7 @@
childNode.audit_created as audit_created,
childNode.audit_modifier as audit_modifier,
childNode.audit_modified as audit_modified,
childNode.audit_accessed as audit_accessed
childNode.audit_accessed as audit_accessed
<if test="prop1qnameId != null">
, prop1.node_id as prop1_node_id,
prop1.qname_id as prop1_qname_id,
@@ -1067,9 +1076,6 @@
#{item}
</foreach>
</if>
<if test="prop1qnameId == null and auditableProps == false">
<include refid="alfresco.node.select_ChildAssoc_OrderBy"/>
</if>
</select>
<!-- GetChildren - with no explicit sorting (or prop filtering) - note: still filtered by child type (and optionally primary or secondary) -->