mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Nested collection (maps, sets, lists) property retrieval
- Single-shot query retrieves ordered view - MLText, HashMap and ArrayList currently supported git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15783 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -68,24 +68,24 @@ CREATE TABLE alf_prop_value
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE alf_prop_collection_link
|
||||
CREATE TABLE alf_prop_link
|
||||
(
|
||||
root_coll_prop_id BIGINT NOT NULL,
|
||||
curr_coll_prop_id BIGINT NOT NULL,
|
||||
key_prop_id BIGINT NOT NULL,
|
||||
root_prop_id BIGINT NOT NULL,
|
||||
current_prop_id BIGINT NOT NULL,
|
||||
value_prop_id BIGINT NOT NULL,
|
||||
INDEX idx_alf_prop_coll_rev (value_prop_id, root_coll_prop_id),
|
||||
PRIMARY KEY (root_coll_prop_id, curr_coll_prop_id, key_prop_id, value_prop_id)
|
||||
key_prop_id BIGINT NOT NULL,
|
||||
INDEX idx_alf_prop_coll_rev (value_prop_id, root_prop_id),
|
||||
PRIMARY KEY (root_prop_id, current_prop_id, value_prop_id, key_prop_id)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
--
|
||||
-- Record script finish
|
||||
--
|
||||
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-PropertyValueTables';
|
||||
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-V3.3-PropertyValueTables', 'Manually executed script upgrade V3.3: PropertyValue Tables',
|
||||
0, 3000, -1, 3001, null, 'UNKOWN', 1, 1, 'Script completed'
|
||||
);
|
||||
-- DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-PropertyValueTables';
|
||||
-- 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-V3.3-PropertyValueTables', 'Manually executed script upgrade V3.3: PropertyValue Tables',
|
||||
-- 0, 3000, -1, 3001, null, 'UNKOWN', 1, 1, 'Script completed'
|
||||
-- );
|
@@ -15,7 +15,8 @@
|
||||
<typeAlias alias="PropertyStringValue" type="org.alfresco.repo.domain.propval.PropertyStringValueEntity"/>
|
||||
<typeAlias alias="PropertyDoubleValue" type="org.alfresco.repo.domain.propval.PropertyDoubleValueEntity"/>
|
||||
<typeAlias alias="PropertyValue" type="org.alfresco.repo.domain.propval.PropertyValueEntity"/>
|
||||
<typeAlias alias="PropertyCollectionLink" type="org.alfresco.repo.domain.propval.PropertyCollectionLinkEntity"/>
|
||||
<typeAlias alias="PropertyLink" type="org.alfresco.repo.domain.propval.PropertyLinkEntity"/>
|
||||
<typeAlias alias="PropertyIdSearchRow" type="org.alfresco.repo.domain.propval.PropertyIdSearchRow"/>
|
||||
|
||||
<!-- -->
|
||||
<!-- Result Maps -->
|
||||
@@ -57,27 +58,29 @@
|
||||
<result property="stringValue" column="string_value" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||
<result property="serializableValue" column="serializable_value" jdbcType="BLOB" javaType="java.lang.Object"/>
|
||||
</resultMap>
|
||||
<resultMap id="result.PropertyCollectionLink" class="PropertyCollectionLink">
|
||||
<result property="rootCollectionPropId" column="root_coll_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="currentCollectionPropId" column="persisted_type" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="keyPropId" column="key_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<resultMap id="result.PropertyLink" class="PropertyLink">
|
||||
<result property="rootPropId" column="root_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="currentPropId" column="current_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="valuePropId" column="value_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="keyPropId" column="key_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
</resultMap>
|
||||
<resultMap id="result.PropertyIdSearchRow" class="PropertyIdSearchRow">
|
||||
<result property="rootPropId" column="root_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="currentPropId" column="current_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="valuePropId" column="value_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="keyPropId" column="key_prop_id" jdbcType="BIGINT" javaType="long"/>
|
||||
<result property="actualTypeId" column="actual_type_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="persistedType" column="persisted_type" jdbcType="TINYINT" javaType="java.lang.Short"/>
|
||||
<result property="longValue" column="long_value" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<result property="doubleValue" column="double_value" jdbcType="DOUBLE" javaType="java.lang.Double"/>
|
||||
<result property="stringValue" column="string_value" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||
<result property="serializableValue" column="serializable_value" jdbcType="BLOB" javaType="java.lang.Object"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- -->
|
||||
<!-- Parameter Maps -->
|
||||
<!-- -->
|
||||
|
||||
<!--
|
||||
<parameterMap id="parameter.ExclusiveLockUpdateMap" class="map">
|
||||
<parameter property="newLockToken" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||
<parameter property="newStartTime" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="newExpiryTime" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="exclusiveLockResourceId" jdbcType="BIGINT" javaType="java.lang.Long"/>
|
||||
<parameter property="oldLockToken" jdbcType="VARCHAR" javaType="java.lang.String"/>
|
||||
</parameterMap>
|
||||
-->
|
||||
|
||||
<!-- -->
|
||||
<!-- SQL Snippets -->
|
||||
<!-- -->
|
||||
@@ -260,32 +263,29 @@
|
||||
</select>
|
||||
|
||||
<!-- Get the property value by ID -->
|
||||
<select id="select.PropertyValueById" parameterClass="PropertyValue" resultMap="result.PropertyValue">
|
||||
<select id="select.PropertyValueById" parameterClass="PropertyValue" resultMap="result.PropertyIdSearchRow">
|
||||
select
|
||||
pv.id as id,
|
||||
pv.actual_type_id as actual_type_id,
|
||||
pv.persisted_type as persisted_type,
|
||||
pv.long_value as long_value,
|
||||
dv.double_value as double_value,
|
||||
sv.string_value as string_value,
|
||||
serv.serializable_value as serializable_value
|
||||
cl.root_prop_id, cl.current_prop_id, cl.value_prop_id, cl.key_prop_id,
|
||||
v.actual_type_id, v.persisted_type,
|
||||
v.long_value, dv.double_value, sv.string_value, serv.serializable_value
|
||||
from
|
||||
alf_prop_value pv
|
||||
left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2)
|
||||
left join alf_prop_string_value sv on (sv.id = pv.long_value and pv.persisted_type = 3)
|
||||
left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4)
|
||||
where
|
||||
pv.id = #id#
|
||||
alf_prop_link cl
|
||||
join alf_prop_value v on (cl.value_prop_id = v.id)
|
||||
left join alf_prop_double_value dv on (dv.id = v.long_value and v.persisted_type = 2)
|
||||
left join alf_prop_string_value sv on (sv.id = v.long_value and (v.persisted_type = 3 || v.persisted_type = 5))
|
||||
left join alf_prop_serializable_value serv on (serv.id = v.long_value and v.persisted_type = 4)
|
||||
where cl.root_prop_id = #id#
|
||||
order by current_prop_id, value_prop_id, key_prop_id
|
||||
</select>
|
||||
|
||||
<insert id="insert.PropertyCollectionLink" parameterClass="PropertyCollectionLink" >
|
||||
insert into alf_prop_collection_link
|
||||
<insert id="insert.PropertyLink" parameterClass="PropertyLink" >
|
||||
insert into alf_prop_link
|
||||
(
|
||||
root_coll_prop_id, curr_coll_prop_id, key_prop_id, value_prop_id
|
||||
root_prop_id, current_prop_id, value_prop_id, key_prop_id
|
||||
)
|
||||
values
|
||||
(
|
||||
#rootCollectionPropId#, #currentCollectionPropId#, #keyPropId#, #valuePropId#
|
||||
#rootPropId#, #currentPropId#, #valuePropId#, #keyPropId#
|
||||
)
|
||||
</insert>
|
||||
|
||||
|
@@ -30,6 +30,7 @@ import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -41,6 +42,8 @@ import org.alfresco.repo.domain.CrcHelper;
|
||||
import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType;
|
||||
import org.alfresco.service.cmr.repository.MLText;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Abstract implementation for Property Value DAO.
|
||||
@@ -59,6 +62,8 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
private static final String CACHE_REGION_PROPERTY_DOUBLE_VALUE = "PropertyDoubleValue";
|
||||
private static final String CACHE_REGION_PROPERTY_VALUE = "PropertyValue";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AbstractPropertyValueDAOImpl.class);
|
||||
|
||||
protected PropertyTypeConverter converter;
|
||||
|
||||
private final PropertyClassCallbackDAO propertyClassDaoCallback;
|
||||
@@ -626,6 +631,29 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
*/
|
||||
private class PropertyValueCallbackDAO extends EntityLookupCallbackDAOAdaptor<Long, Serializable, Serializable>
|
||||
{
|
||||
private final Serializable convertToValue(PropertyValueEntity entity)
|
||||
{
|
||||
if (entity == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Serializable actualValue;
|
||||
if (entity.getPersistedTypeEnum() == PersistedType.CONSTRUCTABLE)
|
||||
{
|
||||
actualValue = entity.getPersistedValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
Long actualTypeId = entity.getActualTypeId();
|
||||
Class<?> actualType = getPropertyClassById(actualTypeId).getSecond();
|
||||
|
||||
Serializable entityValue = entity.getPersistedValue();
|
||||
actualValue = (Serializable) converter.convert(actualType, entityValue);
|
||||
}
|
||||
// Done
|
||||
return actualValue;
|
||||
}
|
||||
|
||||
private final Pair<Long, Serializable> convertEntityToPair(PropertyValueEntity entity)
|
||||
{
|
||||
if (entity == null)
|
||||
@@ -633,13 +661,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
return null;
|
||||
}
|
||||
Long entityId = entity.getId();
|
||||
Serializable entityValue = entity.getPersistedValue();
|
||||
|
||||
// Dig out the class to convert the value to i.e. the actual type of the value
|
||||
Long actualTypeId = entity.getActualTypeId();
|
||||
Class<?> actualType = getPropertyClassById(actualTypeId).getSecond();
|
||||
// Convert it
|
||||
Serializable actualValue = (Serializable) converter.convert(actualType, entityValue);
|
||||
Serializable actualValue = convertToValue(entity);
|
||||
// Done
|
||||
return new Pair<Long, Serializable>(entityId, actualValue);
|
||||
}
|
||||
@@ -669,15 +691,21 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
PropertyValueEntity entity = createPropertyValue(value);
|
||||
Long entityId = entity.getId();
|
||||
// Create the link entry for the property
|
||||
createPropertyLink(entityId, entityId, 0L, entityId);
|
||||
createPropertyLink(entityId, entityId, entityId, 0L);
|
||||
// Done
|
||||
return new Pair<Long, Serializable>(entity.getId(), value);
|
||||
}
|
||||
|
||||
public Pair<Long, Serializable> findByKey(Long key)
|
||||
{
|
||||
PropertyValueEntity entity = findPropertyValueById(key);
|
||||
return convertEntityToPair(entity);
|
||||
List<PropertyIdSearchRow> rows = findPropertyValueById(key);
|
||||
if (rows.size() == 0)
|
||||
{
|
||||
// No results
|
||||
return null;
|
||||
}
|
||||
Serializable value = convertPropertyIdSearchRows(rows);
|
||||
return new Pair<Long, Serializable>(key, value);
|
||||
}
|
||||
|
||||
public Pair<Long, Serializable> findByValue(Serializable value)
|
||||
@@ -694,10 +722,102 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract PropertyValueEntity findPropertyValueById(Long id);
|
||||
protected abstract List<PropertyIdSearchRow> findPropertyValueById(Long id);
|
||||
protected abstract PropertyValueEntity findPropertyValueByValue(Serializable value);
|
||||
protected abstract PropertyValueEntity createPropertyValue(Serializable value);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Serializable convertPropertyIdSearchRows(List<PropertyIdSearchRow> rows)
|
||||
{
|
||||
/*
|
||||
* The results are ordered by the root_prop_id, current_prop_id and value_prop_id.
|
||||
* However, for safety (data patching, etc) we take a first pass to create the
|
||||
* basic properties before hooking them all together in a second pass.
|
||||
*/
|
||||
final Map<Long, Serializable> values = new HashMap<Long, Serializable>(rows.size());
|
||||
List<PropertyLinkEntity> keyRows = new ArrayList<PropertyLinkEntity>(5);
|
||||
Serializable result = null;
|
||||
for (PropertyIdSearchRow row : rows)
|
||||
{
|
||||
PropertyLinkEntity linkEntity = row.getLinkEntity();
|
||||
PropertyValueEntity valueEntity = row.getValueEntity();
|
||||
// Construct the value (Maps and Collections should be CONSTRUCTABLE)
|
||||
Serializable value = propertyValueCallback.convertToValue(valueEntity);
|
||||
// Keep it
|
||||
values.put(new Long(linkEntity.getValuePropId()), value);
|
||||
|
||||
// If this row is a mapping row (the property value ID does not match the current property ID)
|
||||
// then store it for quicker use later
|
||||
if (linkEntity.getCurrentPropId() != linkEntity.getValuePropId())
|
||||
{
|
||||
keyRows.add(linkEntity);
|
||||
}
|
||||
if (linkEntity.getRootPropId() == linkEntity.getValuePropId())
|
||||
{
|
||||
// We found the root
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
|
||||
// We expect a value to be found unless the results are empty
|
||||
if (result == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Now we have all our constructed values and the mapping rows: build the collections
|
||||
for (PropertyLinkEntity propertyLinkEntity : keyRows)
|
||||
{
|
||||
Serializable value = values.get(propertyLinkEntity.getValuePropId());
|
||||
Serializable currentProp = values.get(propertyLinkEntity.getCurrentPropId());
|
||||
if (value == null)
|
||||
{
|
||||
logger.error("No value found for link property: " + propertyLinkEntity);
|
||||
continue;
|
||||
}
|
||||
if (currentProp == null)
|
||||
{
|
||||
logger.error("No current property found for link property: " + propertyLinkEntity);
|
||||
continue;
|
||||
}
|
||||
Long keyId = propertyLinkEntity.getKeyPropId();
|
||||
// put the value into the container
|
||||
if (currentProp instanceof Map<?, ?>)
|
||||
{
|
||||
Pair<Long, Serializable> keyPair = getPropertyValueById(keyId);
|
||||
if (keyPair == null)
|
||||
{
|
||||
logger.error("Current property (map) has key without a value: " + propertyLinkEntity);
|
||||
continue;
|
||||
}
|
||||
Serializable key = keyPair.getSecond();
|
||||
Map<Serializable, Serializable> map = (Map<Serializable, Serializable>) currentProp;
|
||||
map.put(key, value);
|
||||
}
|
||||
else if (currentProp instanceof Set<?>)
|
||||
{
|
||||
// We can ignore the key - it won't make a difference
|
||||
Set<Serializable> set = (Set<Serializable>) currentProp;
|
||||
set.add(value);
|
||||
}
|
||||
// Results 'should' be ordered by key
|
||||
// else if (currentProp instanceof List<?>)
|
||||
// {
|
||||
// // The order is important
|
||||
// List<Serializable> collection = (List<Serializable>) currentProp;
|
||||
// collection.add(keyId.intValue(), value);
|
||||
// }
|
||||
else if (currentProp instanceof Collection<?>)
|
||||
{
|
||||
// The order is important
|
||||
Collection<Serializable> collection = (Collection<Serializable>) currentProp;
|
||||
collection.add(value);
|
||||
}
|
||||
}
|
||||
// This will have put the values into the correct containers
|
||||
return result;
|
||||
}
|
||||
|
||||
//================================
|
||||
// Special handling of maps and collections
|
||||
//================================
|
||||
@@ -726,7 +846,10 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
{
|
||||
clazz = HashMap.class;
|
||||
}
|
||||
Long entityId = createPropertyMapRoot(clazz);
|
||||
|
||||
// Can't use a cached instance as each map is unique. Go direct to entity creation.
|
||||
Long entityId = createPropertyValue(clazz).getId();
|
||||
|
||||
// Use this as the root if this is the first entry into this method
|
||||
if (rootId == null)
|
||||
{
|
||||
@@ -734,7 +857,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
}
|
||||
|
||||
// Create the link entry for the root
|
||||
createPropertyLink(rootId, entityId, 0L, entityId);
|
||||
createPropertyLink(rootId, entityId, entityId, 0L);
|
||||
|
||||
// Now iterate over the entries and create properties for the keys and values
|
||||
for (Map.Entry<K, V> entry : map.entrySet())
|
||||
@@ -752,7 +875,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
Long valueId = valuePair.getFirst();
|
||||
|
||||
// Now write the mapping entry
|
||||
createPropertyLink(rootId, entityId, keyId, valueId);
|
||||
createPropertyLink(rootId, entityId, valueId, keyId);
|
||||
}
|
||||
|
||||
// Done
|
||||
@@ -783,7 +906,10 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
{
|
||||
clazz = ArrayList.class;
|
||||
}
|
||||
Long entityId = createPropertyCollectionRoot(clazz);
|
||||
|
||||
// Can't use a cached instance as each collection is unique. Go direct to entity creation.
|
||||
Long entityId = createPropertyValue(clazz).getId();
|
||||
|
||||
// Use this as the root if this is the first entry into this method
|
||||
if (rootId == null)
|
||||
{
|
||||
@@ -791,7 +917,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
}
|
||||
|
||||
// Create the link entry for the root
|
||||
createPropertyLink(rootId, entityId, 0L, entityId);
|
||||
createPropertyLink(rootId, entityId, entityId, 0L);
|
||||
|
||||
// Now iterate over the entries and create properties for the keys and values
|
||||
long index = 0L;
|
||||
@@ -806,48 +932,24 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
|
||||
Long valueId = valuePair.getFirst();
|
||||
// Now write the mapping entry
|
||||
Long keyId = new Long(index);
|
||||
createPropertyLink(rootId, entityId, keyId, valueId);
|
||||
createPropertyLink(rootId, entityId, valueId, keyId);
|
||||
// Keep iterating
|
||||
index++;
|
||||
}
|
||||
return entityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a property value entry for <b>maps</b>. The class is assumed to
|
||||
* be correct with a default constructor for later reconstruction.
|
||||
* <p/>
|
||||
* This method must not create the associated link property.
|
||||
*
|
||||
* @param clazz The map instance that must be used for re-instantiation.
|
||||
* This must be an instance derived from {@link Map} with a default constructor.
|
||||
* @return Returns the newly-created property ID
|
||||
*/
|
||||
protected abstract Long createPropertyMapRoot(Class<?> clazz);
|
||||
|
||||
/**
|
||||
* Create a property value entry for <b>collections</b>. The class is assumed to
|
||||
* be correct with a default constructor for later reconstruction.
|
||||
* <p/>
|
||||
* This method must not create the associated link property.
|
||||
*
|
||||
* @param clazz The collection instance that must be used for re-instantiation.
|
||||
* This must be an instance derived from {@link Collection} with a default constructor.
|
||||
* @return Returns the newly-created property ID
|
||||
*/
|
||||
protected abstract Long createPropertyCollectionRoot(Class<?> clazz);
|
||||
|
||||
/**
|
||||
* Create an entry for the map or collection link
|
||||
*
|
||||
* @param rootCollectionId the root (entry-point) map or collection ID
|
||||
* @param currentCollectionId the current map or collection ID
|
||||
* @param keyId the map key entity ID or collection position count
|
||||
* @param rootPropId the root (entry-point) map or collection ID
|
||||
* @param currentPropId the current map or collection ID
|
||||
* @param valueId the ID of the entity storing the value (may be another map or collection)
|
||||
* @param keyId the map key entity ID or collection position count
|
||||
*/
|
||||
protected abstract void createPropertyLink(
|
||||
Long rootCollectionId,
|
||||
Long currentCollectionId,
|
||||
Long keyId,
|
||||
Long valueId);
|
||||
Long rootPropId,
|
||||
Long currentPropId,
|
||||
Long valueId,
|
||||
Long keyId);
|
||||
}
|
||||
|
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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 java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Entity bean search results from <b>alf_prop_collections_link</b> and <b>alf_prop_value</b> tables.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.3
|
||||
*/
|
||||
public class PropertyIdSearchRow
|
||||
{
|
||||
private final PropertyLinkEntity linkEntity;
|
||||
private final PropertyValueEntity valueEntity;
|
||||
|
||||
public PropertyIdSearchRow()
|
||||
{
|
||||
linkEntity = new PropertyLinkEntity();
|
||||
valueEntity = new PropertyValueEntity();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int hashCode()
|
||||
// {
|
||||
// return (int) rootCollectionPropId + (int) valuePropId;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean equals(Object obj)
|
||||
// {
|
||||
// if (this == obj)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// else if (obj instanceof PropertyCollectionLinkEntity)
|
||||
// {
|
||||
// PropertyCollectionLinkEntity that = (PropertyCollectionLinkEntity) obj;
|
||||
// return
|
||||
// this.rootCollectionPropId == that.rootCollectionPropId &&
|
||||
// this.currentCollectionPropId == that.currentCollectionPropId &&
|
||||
// this.valuePropId == that.valuePropId &&
|
||||
// this.keyPropId == that.keyPropId;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("PropertyIdSearchRow")
|
||||
.append("[ ").append(linkEntity)
|
||||
.append(", ").append(valueEntity)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public PropertyLinkEntity getLinkEntity()
|
||||
{
|
||||
return linkEntity;
|
||||
}
|
||||
|
||||
public PropertyValueEntity getValueEntity()
|
||||
{
|
||||
return valueEntity;
|
||||
}
|
||||
|
||||
public void setRootPropId(long rootPropId)
|
||||
{
|
||||
linkEntity.setRootPropId(rootPropId);
|
||||
}
|
||||
|
||||
public void setCurrentPropId(long currentPropId)
|
||||
{
|
||||
linkEntity.setCurrentPropId(currentPropId);
|
||||
}
|
||||
|
||||
public void setValuePropId(long valuePropId)
|
||||
{
|
||||
linkEntity.setValuePropId(valuePropId);
|
||||
}
|
||||
|
||||
public void setKeyPropId(long keyPropId)
|
||||
{
|
||||
linkEntity.setKeyPropId(keyPropId);
|
||||
}
|
||||
|
||||
public void setActualTypeId(Long actualTypeId)
|
||||
{
|
||||
valueEntity.setActualTypeId(actualTypeId);
|
||||
}
|
||||
|
||||
public void setPersistedType(Short persistedType)
|
||||
{
|
||||
valueEntity.setPersistedType(persistedType);
|
||||
}
|
||||
|
||||
public void setLongValue(Long longValue)
|
||||
{
|
||||
valueEntity.setLongValue(longValue);
|
||||
}
|
||||
|
||||
public void setStringValue(String stringValue)
|
||||
{
|
||||
valueEntity.setStringValue(stringValue);
|
||||
}
|
||||
|
||||
public void setDoubleValue(Double doubleValue)
|
||||
{
|
||||
valueEntity.setDoubleValue(doubleValue);
|
||||
}
|
||||
|
||||
public void setSerializableValue(Serializable serializableValue)
|
||||
{
|
||||
valueEntity.setSerializableValue(serializableValue);
|
||||
}
|
||||
}
|
@@ -25,26 +25,26 @@
|
||||
package org.alfresco.repo.domain.propval;
|
||||
|
||||
/**
|
||||
* Entity bean for <b>alf_prop_collections_link</b> table.
|
||||
* Entity bean for <b>alf_prop_link</b> table.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 3.3
|
||||
*/
|
||||
public class PropertyCollectionLinkEntity
|
||||
public class PropertyLinkEntity
|
||||
{
|
||||
private long rootCollectionPropId;
|
||||
private long currentCollectionPropId;
|
||||
private long keyPropId;
|
||||
private long rootPropId;
|
||||
private long currentPropId;
|
||||
private long valuePropId;
|
||||
private long keyPropId;
|
||||
|
||||
public PropertyCollectionLinkEntity()
|
||||
public PropertyLinkEntity()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return (int) rootCollectionPropId + (int) valuePropId;
|
||||
return (int) rootPropId + (int) valuePropId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,14 +54,14 @@ public class PropertyCollectionLinkEntity
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obj instanceof PropertyCollectionLinkEntity)
|
||||
else if (obj instanceof PropertyLinkEntity)
|
||||
{
|
||||
PropertyCollectionLinkEntity that = (PropertyCollectionLinkEntity) obj;
|
||||
PropertyLinkEntity that = (PropertyLinkEntity) obj;
|
||||
return
|
||||
this.rootCollectionPropId == that.rootCollectionPropId &&
|
||||
this.currentCollectionPropId == that.currentCollectionPropId &&
|
||||
this.keyPropId == that.keyPropId &&
|
||||
this.valuePropId == that.valuePropId;
|
||||
this.rootPropId == that.rootPropId &&
|
||||
this.currentPropId == that.currentPropId &&
|
||||
this.valuePropId == that.valuePropId &&
|
||||
this.keyPropId == that.keyPropId;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -73,42 +73,33 @@ public class PropertyCollectionLinkEntity
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(512);
|
||||
sb.append("PropertyCollectionsLinkEntity")
|
||||
.append("[ currentCollectionPropId=").append(currentCollectionPropId)
|
||||
.append(", keyPropId=").append(keyPropId)
|
||||
sb.append("PropertyLinkEntity")
|
||||
.append("[ rootPropId=").append(rootPropId)
|
||||
.append(", currentPropId=").append(currentPropId)
|
||||
.append(", valuePropId=").append(valuePropId)
|
||||
.append(", keyPropId=").append(keyPropId)
|
||||
.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public long getRootCollectionPropId()
|
||||
public long getRootPropId()
|
||||
{
|
||||
return rootCollectionPropId;
|
||||
return rootPropId;
|
||||
}
|
||||
|
||||
public void setRootCollectionPropId(long rootCollectionPropId)
|
||||
public void setRootPropId(long rootPropId)
|
||||
{
|
||||
this.rootCollectionPropId = rootCollectionPropId;
|
||||
this.rootPropId = rootPropId;
|
||||
}
|
||||
|
||||
public long getCurrentCollectionPropId()
|
||||
public long getCurrentPropId()
|
||||
{
|
||||
return currentCollectionPropId;
|
||||
return currentPropId;
|
||||
}
|
||||
|
||||
public void setCurrentCollectionPropId(long currentCollectionPropId)
|
||||
public void setCurrentPropId(long currentPropId)
|
||||
{
|
||||
this.currentCollectionPropId = currentCollectionPropId;
|
||||
}
|
||||
|
||||
public long getKeyPropId()
|
||||
{
|
||||
return keyPropId;
|
||||
}
|
||||
|
||||
public void setKeyPropId(long keyPropId)
|
||||
{
|
||||
this.keyPropId = keyPropId;
|
||||
this.currentPropId = currentPropId;
|
||||
}
|
||||
|
||||
public long getValuePropId()
|
||||
@@ -120,4 +111,14 @@ public class PropertyCollectionLinkEntity
|
||||
{
|
||||
this.valuePropId = valuePropId;
|
||||
}
|
||||
|
||||
public long getKeyPropId()
|
||||
{
|
||||
return keyPropId;
|
||||
}
|
||||
|
||||
public void setKeyPropId(long keyPropId)
|
||||
{
|
||||
this.keyPropId = keyPropId;
|
||||
}
|
||||
}
|
@@ -26,9 +26,7 @@ package org.alfresco.repo.domain.propval;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.action.evaluator.compare.PropertyValueComparator;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
/**
|
||||
|
@@ -64,6 +64,18 @@ public class PropertyValueDAOTest extends TestCase
|
||||
txnHelper = transactionService.getRetryingTransactionHelper();
|
||||
|
||||
propertyValueDAO = (PropertyValueDAO) ctx.getBean("propertyValueDAO");
|
||||
|
||||
// Remove the caches to test all functionality
|
||||
removeCaches();
|
||||
}
|
||||
|
||||
private void removeCaches()
|
||||
{
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyClassCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyDateValueCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyDoubleValueCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyStringValueCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyValueCache(null);
|
||||
}
|
||||
|
||||
public void testPropertyClass() throws Exception
|
||||
@@ -238,6 +250,13 @@ public class PropertyValueDAOTest extends TestCase
|
||||
* Tests that the given value can be persisted and retrieved with the same resulting ID
|
||||
*/
|
||||
private void runPropertyValueTest(final Serializable value) throws Exception
|
||||
{
|
||||
runPropertyValueTest(value, true);
|
||||
}
|
||||
/**
|
||||
* Tests that the given value can be persisted and retrieved with the same resulting ID
|
||||
*/
|
||||
private void runPropertyValueTest(final Serializable value, final boolean runValueRetrieval) throws Exception
|
||||
{
|
||||
// Create it (if it doesn't exist)
|
||||
RetryingTransactionCallback<Pair<Long, Serializable>> createValueCallback = new RetryingTransactionCallback<Pair<Long, Serializable>>()
|
||||
@@ -252,6 +271,8 @@ public class PropertyValueDAOTest extends TestCase
|
||||
assertNotNull(entityPair);
|
||||
assertEquals(value, entityPair.getSecond());
|
||||
|
||||
if (runValueRetrieval)
|
||||
{
|
||||
// Retrieve it by value
|
||||
RetryingTransactionCallback<Pair<Long, Serializable>> getValueCallback = new RetryingTransactionCallback<Pair<Long, Serializable>>()
|
||||
{
|
||||
@@ -264,6 +285,7 @@ public class PropertyValueDAOTest extends TestCase
|
||||
final Pair<Long, Serializable> entityPairCheck = txnHelper.doInTransaction(getValueCallback, false);
|
||||
assertNotNull(entityPairCheck);
|
||||
assertEquals(entityPair, entityPairCheck);
|
||||
}
|
||||
|
||||
// Retrieve it by ID
|
||||
RetryingTransactionCallback<Pair<Long, Serializable>> getByIdCallback = new RetryingTransactionCallback<Pair<Long, Serializable>>()
|
||||
@@ -356,15 +378,7 @@ public class PropertyValueDAOTest extends TestCase
|
||||
String value = "MAP-VALUE-" + i;
|
||||
map.put(key, value);
|
||||
}
|
||||
RetryingTransactionCallback<Void> createCallback = new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
propertyValueDAO.getOrCreatePropertyValue(map);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(createCallback);
|
||||
runPropertyValueTest(map, false);
|
||||
}
|
||||
|
||||
public void testPropertyValue_MapOfMapOfStrings() throws Exception
|
||||
@@ -382,15 +396,7 @@ public class PropertyValueDAOTest extends TestCase
|
||||
String key = "OUTERMAP-KEY-" + i;
|
||||
mapOuter.put(key, mapInner);
|
||||
}
|
||||
RetryingTransactionCallback<Void> createCallback = new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
propertyValueDAO.getOrCreatePropertyValue(mapOuter);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(createCallback);
|
||||
runPropertyValueTest(mapOuter, false);
|
||||
}
|
||||
|
||||
public void testPropertyValue_CollectionOfStrings() throws Exception
|
||||
@@ -401,24 +407,7 @@ public class PropertyValueDAOTest extends TestCase
|
||||
String value = "COLL-VALUE-" + i;
|
||||
list.add(value);
|
||||
}
|
||||
RetryingTransactionCallback<Void> createCallback = new RetryingTransactionCallback<Void>()
|
||||
{
|
||||
public Void execute() throws Throwable
|
||||
{
|
||||
propertyValueDAO.getOrCreatePropertyValue(list);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
transactionService.getRetryingTransactionHelper().doInTransaction(createCallback);
|
||||
}
|
||||
|
||||
private void removeCaches()
|
||||
{
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyClassCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyDateValueCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyDoubleValueCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyStringValueCache(null);
|
||||
((AbstractPropertyValueDAOImpl)propertyValueDAO).setPropertyValueCache(null);
|
||||
runPropertyValueTest(list, false);
|
||||
}
|
||||
|
||||
public void testPropertyClass_NoCache() throws Exception
|
||||
|
@@ -56,8 +56,7 @@ public class PropertyValueEntity
|
||||
public static final Short ORDINAL_DOUBLE = 2;
|
||||
public static final Short ORDINAL_STRING = 3;
|
||||
public static final Short ORDINAL_SERIALIZABLE = 4;
|
||||
public static final Short ORDINAL_MAP = 5;
|
||||
public static final Short ORDINAL_COLLECTION = 6;
|
||||
public static final Short ORDINAL_CONSTRUCTABLE = 5;
|
||||
|
||||
/**
|
||||
* Enumeration of persisted types for <b>alf_prop_value.persisted_type</b>.
|
||||
@@ -135,30 +134,17 @@ public class PropertyValueEntity
|
||||
return Serializable.class;
|
||||
}
|
||||
},
|
||||
MAP
|
||||
CONSTRUCTABLE
|
||||
{
|
||||
@Override
|
||||
public Short getOrdinalNumber()
|
||||
{
|
||||
return ORDINAL_MAP;
|
||||
return ORDINAL_CONSTRUCTABLE;
|
||||
}
|
||||
@Override
|
||||
public Class<?> getAssociatedClass()
|
||||
{
|
||||
return Map.class;
|
||||
}
|
||||
},
|
||||
COLLECTION
|
||||
{
|
||||
@Override
|
||||
public Short getOrdinalNumber()
|
||||
{
|
||||
return ORDINAL_COLLECTION;
|
||||
}
|
||||
@Override
|
||||
public Class<?> getAssociatedClass()
|
||||
{
|
||||
return Collection.class;
|
||||
return Class.class;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -213,6 +199,7 @@ public class PropertyValueEntity
|
||||
mapClass.put(Date.class, PersistedType.LONG);
|
||||
mapClass.put(Map.class, PersistedType.SERIALIZABLE); // Will be serialized if encountered
|
||||
mapClass.put(Collection.class, PersistedType.SERIALIZABLE); // Will be serialized if encountered
|
||||
mapClass.put(Class.class, PersistedType.CONSTRUCTABLE); // Will construct a new instance
|
||||
persistedTypesByClass = Collections.unmodifiableMap(mapClass);
|
||||
}
|
||||
|
||||
@@ -281,8 +268,6 @@ public class PropertyValueEntity
|
||||
{
|
||||
switch (persistedTypeEnum)
|
||||
{
|
||||
case MAP:
|
||||
case COLLECTION:
|
||||
case NULL:
|
||||
return null;
|
||||
case LONG:
|
||||
@@ -293,6 +278,21 @@ public class PropertyValueEntity
|
||||
return stringValue;
|
||||
case SERIALIZABLE:
|
||||
return serializableValue;
|
||||
case CONSTRUCTABLE:
|
||||
// Construct an instance
|
||||
try
|
||||
{
|
||||
Class<?> clazz = Class.forName(stringValue);
|
||||
return (Serializable) clazz.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
throw new RuntimeException("Unable to construct instance of class " + stringValue, e);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new RuntimeException("Unable to create new instance of " + stringValue, e);
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Should not be able to get through switch");
|
||||
}
|
||||
@@ -304,16 +304,21 @@ public class PropertyValueEntity
|
||||
*
|
||||
* @param value the value to persist (may be <tt>null</tt>)
|
||||
* @param converter the converter that will perform and type conversion
|
||||
* @return Returns the persisted type value
|
||||
*/
|
||||
public Serializable setValue(Serializable value, PropertyTypeConverter converter)
|
||||
public void setValue(Serializable value, PropertyTypeConverter converter)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
this.persistedType = ORDINAL_NULL;
|
||||
this.persistedTypeEnum = PersistedType.NULL;
|
||||
this.longValue = LONG_ZERO;
|
||||
return longValue;
|
||||
}
|
||||
else if (value instanceof Class<?>)
|
||||
{
|
||||
Class<?> clazz = (Class<?>) value;
|
||||
stringValue = clazz.getName();
|
||||
persistedTypeEnum = PersistedType.CONSTRUCTABLE;
|
||||
persistedType = persistedTypeEnum.getOrdinalNumber();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -329,16 +334,16 @@ public class PropertyValueEntity
|
||||
{
|
||||
case LONG:
|
||||
longValue = converter.convert(Long.class, value);
|
||||
return longValue;
|
||||
break;
|
||||
case DOUBLE:
|
||||
doubleValue = converter.convert(Double.class, value);
|
||||
return doubleValue;
|
||||
break;
|
||||
case STRING:
|
||||
stringValue = converter.convert(String.class, value);
|
||||
return stringValue;
|
||||
break;
|
||||
case SERIALIZABLE:
|
||||
serializableValue = value;
|
||||
return serializableValue;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Should not be able to get through switch");
|
||||
}
|
||||
|
@@ -25,16 +25,15 @@
|
||||
package org.alfresco.repo.domain.propval.ibatis;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.domain.propval.AbstractPropertyValueDAOImpl;
|
||||
import org.alfresco.repo.domain.propval.PropertyClassEntity;
|
||||
import org.alfresco.repo.domain.propval.PropertyCollectionLinkEntity;
|
||||
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.PropertyStringValueEntity;
|
||||
import org.alfresco.repo.domain.propval.PropertyValueEntity;
|
||||
import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType;
|
||||
@@ -71,7 +70,7 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
|
||||
private static final String SELECT_PROPERTY_VALUE_BY_STRING_VALUE = "select.PropertyValueByStringValue";
|
||||
private static final String INSERT_PROPERTY_VALUE = "insert.PropertyValue";
|
||||
|
||||
private static final String INSERT_PROPERTY_COLLECTION_LINK = "insert.PropertyCollectionLink";
|
||||
private static final String INSERT_PROPERTY_LINK = "insert.PropertyLink";
|
||||
|
||||
private SqlMapClientTemplate template;
|
||||
|
||||
@@ -255,16 +254,17 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
|
||||
// 'alf_prop_value' accessors
|
||||
//================================
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected PropertyValueEntity findPropertyValueById(Long id)
|
||||
protected List<PropertyIdSearchRow> findPropertyValueById(Long id)
|
||||
{
|
||||
PropertyValueEntity entity = new PropertyValueEntity();
|
||||
entity.setId(id);
|
||||
entity = (PropertyValueEntity) template.queryForObject(
|
||||
List<PropertyIdSearchRow> results = (List<PropertyIdSearchRow>) template.queryForList(
|
||||
SELECT_PROPERTY_VALUE_BY_ID,
|
||||
entity);
|
||||
// Done
|
||||
return entity;
|
||||
return results;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -367,6 +367,7 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
|
||||
insertEntity.setLongValue(insertDoublePair.getFirst());
|
||||
break;
|
||||
case STRING:
|
||||
case CONSTRUCTABLE:
|
||||
String stringValue = insertEntity.getStringValue();
|
||||
Pair<Long, String> insertStringPair = getOrCreatePropertyStringValue(stringValue);
|
||||
insertEntity.setLongValue(insertStringPair.getFirst());
|
||||
@@ -391,61 +392,19 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
|
||||
return insertEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long createPropertyMapRoot(Class<?> clazz)
|
||||
{
|
||||
if (!Map.class.isAssignableFrom(clazz))
|
||||
{
|
||||
throw new IllegalArgumentException("Map root must be a Map instance");
|
||||
}
|
||||
final Pair<Long, Class<?>> clazzPair = getOrCreatePropertyClass(clazz);
|
||||
final Long actualTypeId = clazzPair.getFirst();
|
||||
|
||||
// Construct a property value to represent the collection
|
||||
PropertyValueEntity insertEntity = new PropertyValueEntity();
|
||||
// We have to set the persisted type manually
|
||||
insertEntity.setPersistedType(PersistedType.MAP.getOrdinalNumber());
|
||||
insertEntity.setLongValue(PropertyValueEntity.LONG_ZERO);
|
||||
insertEntity.setActualTypeId(actualTypeId);
|
||||
Long collectionId = (Long) template.insert(INSERT_PROPERTY_VALUE, insertEntity);
|
||||
// Done
|
||||
return collectionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Long createPropertyCollectionRoot(Class<?> clazz)
|
||||
{
|
||||
if (!Collection.class.isAssignableFrom(clazz))
|
||||
{
|
||||
throw new IllegalArgumentException("Collection root must be a Collection instance");
|
||||
}
|
||||
final Pair<Long, Class<?>> clazzPair = getOrCreatePropertyClass(clazz);
|
||||
final Long actualTypeId = clazzPair.getFirst();
|
||||
|
||||
// Construct a property value to represent the collection
|
||||
PropertyValueEntity insertEntity = new PropertyValueEntity();
|
||||
// We have to set the persisted type manually
|
||||
insertEntity.setPersistedType(PersistedType.COLLECTION.getOrdinalNumber());
|
||||
insertEntity.setLongValue(PropertyValueEntity.LONG_ZERO);
|
||||
insertEntity.setActualTypeId(actualTypeId);
|
||||
Long collectionId = (Long) template.insert(INSERT_PROPERTY_VALUE, insertEntity);
|
||||
// Done
|
||||
return collectionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createPropertyLink(
|
||||
Long rootCollectionId,
|
||||
Long currentCollectionId,
|
||||
Long keyId,
|
||||
Long valueId)
|
||||
Long rootPropId,
|
||||
Long currentPropId,
|
||||
Long valueId,
|
||||
Long keyId)
|
||||
{
|
||||
PropertyCollectionLinkEntity insertEntity = new PropertyCollectionLinkEntity();
|
||||
insertEntity.setRootCollectionPropId(rootCollectionId);
|
||||
insertEntity.setCurrentCollectionPropId(currentCollectionId);
|
||||
insertEntity.setKeyPropId(keyId);
|
||||
PropertyLinkEntity insertEntity = new PropertyLinkEntity();
|
||||
insertEntity.setRootPropId(rootPropId);
|
||||
insertEntity.setCurrentPropId(currentPropId);
|
||||
insertEntity.setValuePropId(valueId);
|
||||
template.insert(INSERT_PROPERTY_COLLECTION_LINK, insertEntity);
|
||||
insertEntity.setKeyPropId(keyId);
|
||||
template.insert(INSERT_PROPERTY_LINK, insertEntity);
|
||||
// Done
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user