diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml index 234f3ad293..b11d50ee5c 100644 --- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml @@ -13,6 +13,7 @@ + @@ -249,7 +250,7 @@ - select pv.id as id, pv.actual_type_id as actual_type_id, @@ -263,7 +264,8 @@ join alf_prop_string_value sv on (sv.id = pv.long_value and pv.persisted_type = #persistedType#) where pv.actual_type_id = #actualTypeId# and - sv.string_value = #stringValue# + sv.string_end_lower = #stringEndLower# and + sv.string_crc = #stringCrc# diff --git a/source/java/org/alfresco/repo/domain/propval/PropertyStringQueryEntity.java b/source/java/org/alfresco/repo/domain/propval/PropertyStringQueryEntity.java new file mode 100644 index 0000000000..a50094c865 --- /dev/null +++ b/source/java/org/alfresco/repo/domain/propval/PropertyStringQueryEntity.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005-2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.domain.propval; + +import org.alfresco.repo.domain.CrcHelper; +import org.alfresco.util.Pair; + +/** + * Entity bean for querying against the alf_prop_string_value table. + * + * @author Derek Hulley + * @since 3.2 + */ +public class PropertyStringQueryEntity +{ + private final Short persistedType; + private final Long actualTypeId; + private final String stringValue; + private final String stringEndLower; + private final Long stringCrc; + + public PropertyStringQueryEntity(Short persistedType, Long actualTypeId, String value) + { + this.persistedType = persistedType; + this.actualTypeId = actualTypeId; + + stringValue = value; + // Calculate the crc value from the original value + Pair crcPair = CrcHelper.getStringCrcPair(value, 16, false, true); + stringEndLower = crcPair.getFirst(); + stringCrc = crcPair.getSecond(); + } + + public Short getPersistedType() + { + return persistedType; + } + + public Long getActualTypeId() + { + return actualTypeId; + } + + public String getStringValue() + { + return stringValue; + } + + public String getStringEndLower() + { + return stringEndLower; + } + + public Long getStringCrc() + { + return stringCrc; + } +} diff --git a/source/java/org/alfresco/repo/domain/propval/ibatis/PropertyValueDAOImpl.java b/source/java/org/alfresco/repo/domain/propval/ibatis/PropertyValueDAOImpl.java index 1233f2f833..6b57cc3278 100644 --- a/source/java/org/alfresco/repo/domain/propval/ibatis/PropertyValueDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/propval/ibatis/PropertyValueDAOImpl.java @@ -34,6 +34,7 @@ import org.alfresco.repo.domain.propval.PropertyDateValueEntity; import org.alfresco.repo.domain.propval.PropertyDoubleValueEntity; import org.alfresco.repo.domain.propval.PropertyIdSearchRow; import org.alfresco.repo.domain.propval.PropertyLinkEntity; +import org.alfresco.repo.domain.propval.PropertyStringQueryEntity; import org.alfresco.repo.domain.propval.PropertyStringValueEntity; import org.alfresco.repo.domain.propval.PropertyValueEntity; import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType; @@ -168,17 +169,26 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl return value; } + @SuppressWarnings("unchecked") @Override protected Long findStringValueByValue(String value) { PropertyStringValueEntity entity = new PropertyStringValueEntity(); entity.setValue(value); - Long id = (Long) template.queryForObject( + List rows = (List) template.queryForList( SELECT_PROPERTY_STRING_VALUE_BY_VALUE, - entity); + entity, + 0, 1); // The CRC match prevents incorrect results from coming back. Although there could be // several matches, we are sure that the matches are case-sensitive. - return id; + if (rows.size() > 0) + { + return rows.get(0); + } + else + { + return null; + } } @Override @@ -215,8 +225,9 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl entity.setDoubleValue(value); List results = (List) template.queryForList( SELECT_PROPERTY_DOUBLE_VALUE_BY_VALUE, - entity); - // There coult be several matches, so take the first one + entity, + 0, 1); + // There could be several matches, so just get one if (results.size() > 0) { return results.get(0); @@ -277,10 +288,11 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl // How would it be persisted? PersistedType persistedType = queryEntity.getPersistedTypeEnum(); + Short persistedTypeId = queryEntity.getPersistedType(); // Query based on the the persistable value type String query = null; - boolean singleResult = true; // false if multiple query results are possible + Object queryObject = queryEntity; // Handle each persisted type individually @@ -294,8 +306,12 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl query = SELECT_PROPERTY_VALUE_BY_DOUBLE_VALUE; break; case STRING: + // It's best to query using the CRC and short end-value query = SELECT_PROPERTY_VALUE_BY_STRING_VALUE; - singleResult = false; + queryObject = new PropertyStringQueryEntity( + persistedTypeId, + actualTypeId, + queryEntity.getStringValue()); break; case SERIALIZABLE: // No query @@ -308,32 +324,21 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl PropertyValueEntity result = null; if (query != null) { - if (singleResult) + List results = (List) template.queryForList( + query, + queryObject, + 0, 1); // Only want one result + for (PropertyValueEntity row : results) { - result = (PropertyValueEntity) template.queryForObject(query, queryEntity); - } - else - { - Serializable queryValue = queryEntity.getPersistedValue(); - List results = (List) template.queryForList( - query, - queryEntity); - for (PropertyValueEntity row : results) - { - if (queryValue.equals(row.getPersistedValue())) - { - // We have a match - result = row; - break; - } - } + result = row; + break; } } // Done return result; } - + @Override protected PropertyValueEntity createPropertyValue(Serializable value) {