diff --git a/config/alfresco/dbscripts/db-schema-context.xml b/config/alfresco/dbscripts/db-schema-context.xml
index c5680f9aab..1415fc6a24 100644
--- a/config/alfresco/dbscripts/db-schema-context.xml
+++ b/config/alfresco/dbscripts/db-schema-context.xml
@@ -56,6 +56,7 @@
+
diff --git a/config/alfresco/dbscripts/upgrade/4.1/org.hibernate.dialect.Dialect/update-activiti-nullable-columns.sql b/config/alfresco/dbscripts/upgrade/4.1/org.hibernate.dialect.Dialect/update-activiti-nullable-columns.sql
new file mode 100644
index 0000000000..67dc4692dc
--- /dev/null
+++ b/config/alfresco/dbscripts/upgrade/4.1/org.hibernate.dialect.Dialect/update-activiti-nullable-columns.sql
@@ -0,0 +1,48 @@
+--
+-- Title: Update ALF_ACTIVITY_FEED and ALF_ACTIVITY_FEED_CONTROL tables by setting special @@NULL@@ value for nullable columns feed_user_id and site_network.
+-- Database: Generic
+-- Since: V4.1 Schema 5149
+-- Author: Pavel Yurkevich
+--
+-- Please contact support@alfresco.com if you need assistance with the upgrade.
+--
+-- MNT-9532: SQL performance issue - WHERE ... IS NULL statements
+--
+-- Record script finish
+--
+-- Since oracle treats empty strings as NULLs, we have to use following format in where clause
+-- ((feed_user_id IS NULL AND '' IS NULL) OR feed_user_id = '')
+-- (feed_user_id IS NULL AND '' IS NULL) is Oracle specific part
+
+--FOREACH alf_activity_feed.id system.upgrade.alf_activity_feed.batchsize
+UPDATE alf_activity_feed af
+ SET feed_user_id = '@@NULL@@'
+ WHERE
+ ((feed_user_id IS NULL AND '' IS NULL) OR feed_user_id = '') AND af.id >= ${LOWERBOUND} AND af.id <= ${UPPERBOUND};
+
+--FOREACH alf_activity_feed.id system.upgrade.alf_activity_feed.batchsize
+UPDATE alf_activity_feed af
+ SET site_network = '@@NULL@@'
+ WHERE
+ ((site_network IS NULL AND '' IS NULL) OR site_network = '') AND af.id >= ${LOWERBOUND} AND af.id <= ${UPPERBOUND};
+
+--FOREACH alf_activity_feed_control.id system.upgrade.alf_activity_feed_control.batchsize
+UPDATE alf_activity_feed_control afc
+ SET feed_user_id = '@@NULL@@'
+ WHERE
+ ((feed_user_id IS NULL AND '' IS NULL) OR feed_user_id = '') AND afc.id >= ${LOWERBOUND} AND afc.id <= ${UPPERBOUND};
+
+--FOREACH alf_activity_feed_control.id system.upgrade.alf_activity_feed_control.batchsize
+UPDATE alf_activity_feed_control afc
+ SET site_network = '@@NULL@@'
+ WHERE
+ ((site_network IS NULL AND '' IS NULL) OR site_network = '') AND afc.id >= ${LOWERBOUND} AND afc.id <= ${UPPERBOUND};
+
+DELETE FROM alf_applied_patch WHERE id = 'patch.db-V4.1-update-activiti-nullable-columns';
+INSERT INTO alf_applied_patch
+ (id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
+ VALUES
+ (
+ 'patch.db-V4.1-update-activiti-nullable-columns', 'Manually executed script upgrade V4.1: ALF_ACTIVITY_FEED and ALF_ACTIVITY_FEED_CONTROL tables. Updates feed_user_id and site_network columns with @@NULL@@ value',
+ 0, 5149, -1, 5150, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
+ );
\ No newline at end of file
diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/activities-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/activities-common-SqlMap.xml
index 3e20628a2e..c79ee38bfa 100644
--- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/activities-common-SqlMap.xml
+++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/activities-common-SqlMap.xml
@@ -87,22 +87,22 @@
-
+
+
+
+ 0
+ 8005
+ 8006
+
+ classpath:alfresco/dbscripts/upgrade/4.1/${db.script.dialect}/update-activiti-nullable-columns.sql
+
+
+
diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties
index 7e363998c7..612754dee5 100644
--- a/config/alfresco/version.properties
+++ b/config/alfresco/version.properties
@@ -23,4 +23,4 @@ version.build=r@scm-revision@-b@build-number@
# Schema number
-version.schema=8005
+version.schema=8006
diff --git a/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java b/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java
index 51be2d348c..ba20a7e97b 100644
--- a/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java
+++ b/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java
@@ -39,6 +39,7 @@ import java.util.Map;
import java.util.Set;
import org.alfresco.repo.activities.post.lookup.PostLookup;
+import org.alfresco.repo.domain.activities.ActivitiesDAO;
import org.alfresco.repo.domain.activities.ActivityFeedDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.domain.activities.ActivityPostEntity;
@@ -649,7 +650,7 @@ public abstract class FeedTaskProcessor
for (FeedControlEntity feedControl : feedControls)
{
- if (((feedControl.getSiteNetwork() == null) || (feedControl.getSiteNetwork().length() == 0)) && (feedControl.getAppTool() != null))
+ if (ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE.equals(feedControl.getSiteNetwork()) && (feedControl.getAppTool() != null))
{
if (feedControl.getAppTool().equals(activityPost.getAppTool()))
{
diff --git a/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java b/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java
index 930f958fc5..ec9ce858ab 100644
--- a/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java
+++ b/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.domain.activities.ActivitiesDAO;
import org.alfresco.repo.domain.activities.ActivityFeedDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.lock.JobLockService;
@@ -305,7 +306,7 @@ public class FeedCleaner implements NodeServicePolicies.BeforeDeleteNodePolicy
String feedUserId = userFeedTooMany.getFeedUserId();
// Rather than filter out the two usernames that indicate site-specific
// feed entries, we can just filter them out now.
- if (feedUserId == null || feedUserId.length() == 0)
+ if (ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE.equals(feedUserId))
{
if (logger.isTraceEnabled())
{
diff --git a/source/java/org/alfresco/repo/domain/activities/ActivitiesDAO.java b/source/java/org/alfresco/repo/domain/activities/ActivitiesDAO.java
index 1471f5cc4d..48b54594be 100644
--- a/source/java/org/alfresco/repo/domain/activities/ActivitiesDAO.java
+++ b/source/java/org/alfresco/repo/domain/activities/ActivitiesDAO.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2010 Alfresco Software Limited.
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -25,6 +25,8 @@ import java.sql.SQLException;
*/
public interface ActivitiesDAO
{
+ public static final String KEY_ACTIVITY_NULL_VALUE = "@@NULL@@";
+
public void startTransaction() throws SQLException;
public void commitTransaction() throws SQLException;
diff --git a/source/java/org/alfresco/repo/domain/activities/ActivityFeedEntity.java b/source/java/org/alfresco/repo/domain/activities/ActivityFeedEntity.java
index 31b2828380..cbc16aa17a 100644
--- a/source/java/org/alfresco/repo/domain/activities/ActivityFeedEntity.java
+++ b/source/java/org/alfresco/repo/domain/activities/ActivityFeedEntity.java
@@ -46,10 +46,10 @@ public class ActivityFeedEntity
private Long id; // internal DB-generated id
private String activityType;
private String activitySummary;
- private String feedUserId;
+ private String feedUserId = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String postUserId;
private NodeRef postUserAvatarNodeRef;
- private String siteNetwork;
+ private String siteNetwork = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String appTool;
private Date postDate;
private Date feedDate; // for debug
@@ -83,7 +83,10 @@ public class ActivityFeedEntity
public void setFeedUserId(String userid)
{
- this.feedUserId = userid;
+ if (userid != null && userid.length() > 0)
+ {
+ this.feedUserId = userid;
+ }
}
public String getPostUserId()
@@ -103,7 +106,10 @@ public class ActivityFeedEntity
public void setSiteNetwork(String siteNetwork)
{
- this.siteNetwork = siteNetwork;
+ if (siteNetwork != null && siteNetwork.length() > 0)
+ {
+ this.siteNetwork = siteNetwork;
+ }
}
public String getActivityType()
diff --git a/source/java/org/alfresco/repo/domain/activities/ActivityFeedQueryEntity.java b/source/java/org/alfresco/repo/domain/activities/ActivityFeedQueryEntity.java
index 7bfe72b193..3bc4504f77 100644
--- a/source/java/org/alfresco/repo/domain/activities/ActivityFeedQueryEntity.java
+++ b/source/java/org/alfresco/repo/domain/activities/ActivityFeedQueryEntity.java
@@ -28,9 +28,15 @@ public class ActivityFeedQueryEntity
{
private Long minId;
private Long maxId;
+ private int maxFeedSize;
private String feedUserId;
private String siteNetwork;
+ public String getNullValue()
+ {
+ return ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
+ }
+
public Long getMinId()
{
return minId;
@@ -51,6 +57,16 @@ public class ActivityFeedQueryEntity
this.maxId = maxId;
}
+ public int getMaxFeedSize()
+ {
+ return maxFeedSize;
+ }
+
+ public void setMaxFeedSize(int maxFeedSize)
+ {
+ this.maxFeedSize = maxFeedSize;
+ }
+
public String getFeedUserId()
{
return feedUserId;
diff --git a/source/java/org/alfresco/repo/domain/activities/FeedControlEntity.java b/source/java/org/alfresco/repo/domain/activities/FeedControlEntity.java
index fce7f215d1..af5ed2f40a 100644
--- a/source/java/org/alfresco/repo/domain/activities/FeedControlEntity.java
+++ b/source/java/org/alfresco/repo/domain/activities/FeedControlEntity.java
@@ -28,8 +28,8 @@ import org.alfresco.service.cmr.activities.FeedControl;
public class FeedControlEntity
{
private Long id; // internal DB-generated id
- private String feedUserId;
- private String siteNetwork;
+ private String feedUserId = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
+ private String siteNetwork = ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE;
private String appTool;
private Date lastModified; // when inserted
@@ -44,13 +44,22 @@ public class FeedControlEntity
public FeedControlEntity(String feedUserId)
{
- this.feedUserId = feedUserId;
+ if (feedUserId != null && feedUserId.length() > 0)
+ {
+ this.feedUserId = feedUserId;
+ }
}
public FeedControlEntity(String feedUserId, FeedControl feedControl)
{
- this.feedUserId = feedUserId;
- this.siteNetwork = feedControl.getSiteId();
+ if (feedUserId != null && feedUserId.length() > 0)
+ {
+ this.feedUserId = feedUserId;
+ }
+ if (feedControl.getSiteId() != null && feedControl.getSiteId().length() > 0)
+ {
+ this.siteNetwork = feedControl.getSiteId();
+ }
this.appTool = feedControl.getAppToolId();
this.lastModified = new Date();
}
@@ -77,7 +86,10 @@ public class FeedControlEntity
public void setSiteNetwork(String siteNetwork)
{
- this.siteNetwork = siteNetwork;
+ if (siteNetwork != null && siteNetwork.length() > 0)
+ {
+ this.siteNetwork = siteNetwork;
+ }
}
public String getAppTool()
@@ -97,7 +109,10 @@ public class FeedControlEntity
public void setFeedUserId(String feedUserId)
{
- this.feedUserId = feedUserId;
+ if (feedUserId != null && feedUserId.length() > 0)
+ {
+ this.feedUserId = feedUserId;
+ }
}
public Date getLastModified()
diff --git a/source/java/org/alfresco/repo/domain/activities/ibatis/ActivityFeedDAOImpl.java b/source/java/org/alfresco/repo/domain/activities/ibatis/ActivityFeedDAOImpl.java
index 0d2d323ed3..27c48717d7 100644
--- a/source/java/org/alfresco/repo/domain/activities/ibatis/ActivityFeedDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/activities/ibatis/ActivityFeedDAOImpl.java
@@ -127,7 +127,10 @@ public class ActivityFeedDAOImpl extends ActivitiesDAOImpl implements ActivityFe
@Override
public List selectUserFeedsToClean(int maxFeedSize) throws SQLException
{
- return template.selectList("alfresco.activities.select_activity_user_feeds_greater_than_max", maxFeedSize);
+ ActivityFeedQueryEntity params = new ActivityFeedQueryEntity();
+ params.setMaxFeedSize(maxFeedSize);
+
+ return template.selectList("alfresco.activities.select_activity_user_feeds_greater_than_max", params);
}
@Override
@@ -197,7 +200,10 @@ public class ActivityFeedDAOImpl extends ActivitiesDAOImpl implements ActivityFe
@Override
public List selectSiteFeedsToClean(int maxFeedSize) throws SQLException
{
- return template.selectList("alfresco.activities.select_activity_site_feeds_greater_than_max", maxFeedSize);
+ ActivityFeedQueryEntity params = new ActivityFeedQueryEntity();
+ params.setMaxFeedSize(maxFeedSize);
+
+ return template.selectList("alfresco.activities.select_activity_site_feeds_greater_than_max", params);
}
@SuppressWarnings("unchecked")
diff --git a/source/test-java/org/alfresco/repo/activities/feed/FeedNotifierTest.java b/source/test-java/org/alfresco/repo/activities/feed/FeedNotifierTest.java
index 33e8ba9d07..f73d77d171 100644
--- a/source/test-java/org/alfresco/repo/activities/feed/FeedNotifierTest.java
+++ b/source/test-java/org/alfresco/repo/activities/feed/FeedNotifierTest.java
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.post.lookup.PostLookup;
+import org.alfresco.repo.domain.activities.ActivitiesDAO;
import org.alfresco.repo.domain.activities.ActivityFeedEntity;
import org.alfresco.repo.domain.activities.ActivityPostDAO;
import org.alfresco.repo.management.subsystems.ChildApplicationContextFactory;
@@ -317,7 +318,7 @@ public class FeedNotifierTest
boolean found = false;
for (ActivityFeedEntity feed : feeds)
{
- if (feed.getActivityType().equals(activityType) && (feed.getSiteNetwork() == null || feed.getSiteNetwork().isEmpty()))
+ if (feed.getActivityType().equals(activityType) && ActivitiesDAO.KEY_ACTIVITY_NULL_VALUE.equals(feed.getSiteNetwork()))
{
found = true;
}