Added table and DAO: alf_prop_unique_ctx

- Ensure uniqueness across any three (incl. null) Serializable values
 - Required to support RM rma:identifier contextual uniqueness

DB Update for MySQL:

drop table if exists alf_prop_unique_ctx;
CREATE TABLE alf_prop_unique_ctx
(
   id BIGINT NOT NULL AUTO_INCREMENT,
   version SMALLINT NOT NULL,
   value1_prop_id BIGINT NOT NULL,
   value2_prop_id BIGINT NOT NULL,
   value3_prop_id BIGINT NOT NULL,
   UNIQUE INDEX idx_alf_prop_unique_ctx (value1_prop_id, value2_prop_id, value3_prop_id),
   CONSTRAINT fk_alf_prop_unique_ctx_1 FOREIGN KEY (value1_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
   CONSTRAINT fk_alf_prop_unique_ctx_2 FOREIGN KEY (value2_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
   CONSTRAINT fk_alf_prop_unique_ctx_3 FOREIGN KEY (value3_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
   PRIMARY KEY (id)
);

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16417 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-09-21 22:20:29 +00:00
parent 53fddcb5f7
commit 14515875c7
9 changed files with 540 additions and 26 deletions

View File

@@ -93,6 +93,20 @@ CREATE TABLE alf_prop_link
PRIMARY KEY (root_prop_id, contained_in, prop_index) PRIMARY KEY (root_prop_id, contained_in, prop_index)
) ENGINE=InnoDB; ) ENGINE=InnoDB;
CREATE TABLE alf_prop_unique_ctx
(
id BIGINT NOT NULL AUTO_INCREMENT,
version SMALLINT NOT NULL,
value1_prop_id BIGINT NOT NULL,
value2_prop_id BIGINT NOT NULL,
value3_prop_id BIGINT NOT NULL,
UNIQUE INDEX idx_alf_prop_unique_ctx (value1_prop_id, value2_prop_id, value3_prop_id),
CONSTRAINT fk_alf_prop_unique_ctx_1 FOREIGN KEY (value1_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
CONSTRAINT fk_alf_prop_unique_ctx_2 FOREIGN KEY (value2_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
CONSTRAINT fk_alf_prop_unique_ctx_3 FOREIGN KEY (value3_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE,
PRIMARY KEY (id)
)
-- --
-- Record script finish -- Record script finish
-- --

View File

@@ -19,6 +19,7 @@
<typeAlias alias="PropertyValue" type="org.alfresco.repo.domain.propval.PropertyValueEntity"/> <typeAlias alias="PropertyValue" type="org.alfresco.repo.domain.propval.PropertyValueEntity"/>
<typeAlias alias="PropertyRoot" type="org.alfresco.repo.domain.propval.PropertyRootEntity"/> <typeAlias alias="PropertyRoot" type="org.alfresco.repo.domain.propval.PropertyRootEntity"/>
<typeAlias alias="PropertyLink" type="org.alfresco.repo.domain.propval.PropertyLinkEntity"/> <typeAlias alias="PropertyLink" type="org.alfresco.repo.domain.propval.PropertyLinkEntity"/>
<typeAlias alias="PropertyUniqueContext" type="org.alfresco.repo.domain.propval.PropertyUniqueContextEntity"/>
<typeAlias alias="PropertyIdSearchRow" type="org.alfresco.repo.domain.propval.PropertyIdSearchRow"/> <typeAlias alias="PropertyIdSearchRow" type="org.alfresco.repo.domain.propval.PropertyIdSearchRow"/>
<!-- --> <!-- -->
@@ -74,6 +75,17 @@
<result property="keyPropId" column="link_key_prop_id" jdbcType="BIGINT" javaType="long"/> <result property="keyPropId" column="link_key_prop_id" jdbcType="BIGINT" javaType="long"/>
<result property="valuePropId" column="link_value_prop_id" jdbcType="BIGINT" javaType="long"/> <result property="valuePropId" column="link_value_prop_id" jdbcType="BIGINT" javaType="long"/>
</resultMap> </resultMap>
<resultMap id="result_PropertyRoot" class="PropertyRoot">
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="version" column="version" jdbcType="TINYINT" javaType="java.lang.Short"/>
</resultMap>
<resultMap id="result_PropertyUniqueContext" class="PropertyUniqueContext">
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="version" column="version" jdbcType="TINYINT" javaType="java.lang.Short"/>
<result property="value1PropId" column="value1_prop_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="value2PropId" column="value2_prop_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="value3PropId" column="value3_prop_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</resultMap>
<resultMap id="result_PropertyIdSearchRow" class="PropertyIdSearchRow"> <resultMap id="result_PropertyIdSearchRow" class="PropertyIdSearchRow">
<!-- If we use nested ResultMaps, then this ResultMap can't be embedded... --> <!-- If we use nested ResultMaps, then this ResultMap can't be embedded... -->
<result property="rootPropId" column="link_root_prop_id" jdbcType="BIGINT" javaType="long"/> <result property="rootPropId" column="link_root_prop_id" jdbcType="BIGINT" javaType="long"/>
@@ -134,6 +146,11 @@
values (?) values (?)
</sql> </sql>
<sql id="insert_PropertyUniqueContext_AutoIncrement">
insert into alf_prop_unique_ctx (version, value1_prop_id, value2_prop_id, value3_prop_id)
values (#version#, #value1PropId#, #value2PropId#, #value3PropId#)
</sql>
<!-- --> <!-- -->
<!-- Statements --> <!-- Statements -->
<!-- --> <!-- -->
@@ -347,7 +364,7 @@
pl.root_prop_id = #id# pl.root_prop_id = #id#
</select> </select>
<select id="select_PropertyRootById" parameterClass="PropertyRoot" resultClass="PropertyRoot"> <select id="select_PropertyRootById" parameterClass="PropertyRoot" resultMap="result_PropertyRoot">
select select
id, id,
version version
@@ -394,4 +411,54 @@
root_prop_id = #id# root_prop_id = #id#
</delete> </delete>
<select id="select_PropertyUniqueContextById" parameterClass="PropertyUniqueContext" resultMap="result_PropertyUniqueContext">
select
id,
version,
value1_prop_id,
value2_prop_id,
value3_prop_id
from
alf_prop_unique_ctx
where
id = #id#
</select>
<select id="select_PropertyUniqueContextByValues" parameterClass="PropertyUniqueContext" resultMap="result_PropertyUniqueContext">
select
id,
version,
value1_prop_id,
value2_prop_id,
value3_prop_id
from
alf_prop_unique_ctx
where
value1_prop_id = #value1PropId# and
value2_prop_id = #value2PropId# and
value3_prop_id = #value3PropId#
</select>
<update id="update_PropertyUniqueContext" parameterClass="PropertyUniqueContext">
update
alf_prop_unique_ctx
set
version = #version#,
value1_prop_id = #value1PropId#,
value2_prop_id = #value2PropId#,
value3_prop_id = #value3PropId#
where
id = #id#
<isGreaterThan property="version" compareValue="1">
and version = ((#version#-1))
</isGreaterThan>
</update>
<delete id="delete_PropertyUniqueContextById" parameterClass="PropertyUniqueContext">
delete from
alf_prop_unique_ctx
where
id = #id#
</delete>
</sqlMap> </sqlMap>

View File

@@ -48,4 +48,11 @@
</selectKey> </selectKey>
</insert> </insert>
<insert id="insert_PropertyUniqueContext" parameterClass="PropertyUniqueContext" >
<include refid="insert_PropertyUniqueContext_AutoIncrement"/>
<selectKey resultClass="long" keyProperty="id" type="post">
KEY_COLUMN:GENERATED_KEY
</selectKey>
</insert>
</sqlMap> </sqlMap>

View File

@@ -40,6 +40,7 @@ import org.alfresco.repo.cache.lookup.EntityLookupCache;
import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAOAdaptor; import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAOAdaptor;
import org.alfresco.repo.domain.CrcHelper; import org.alfresco.repo.domain.CrcHelper;
import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType; import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType;
import org.alfresco.repo.props.PropertyUniqueConstraintViolation;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -1059,6 +1060,102 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
*/ */
protected abstract int deletePropertyLinks(Long rootPropId); protected abstract int deletePropertyLinks(Long rootPropId);
//================================
// 'alf_prop_unique_ctx' accessors
//================================
public Long createPropertyUniqueContext(Serializable value1, Serializable value2, Serializable value3)
{
// Translate the properties. Null values are acceptable
Long id1 = getOrCreatePropertyValue(value1).getFirst();
Long id2 = getOrCreatePropertyValue(value2).getFirst();
Long id3 = getOrCreatePropertyValue(value3).getFirst();
try
{
PropertyUniqueContextEntity entity = createPropertyUniqueContext(id1, id2, id3);
if (logger.isDebugEnabled())
{
logger.debug(
"Created unique property context: \n" +
" Values: " + value1 + "-" + value2 + "-" + value3 + "\n" +
" Result: " + entity);
}
return entity.getId();
}
catch (Throwable e)
{
throw new PropertyUniqueConstraintViolation(value1, value2, value3);
}
}
public Long getPropertyUniqueContext(Serializable value1, Serializable value2, Serializable value3)
{
// Translate the properties. Null values are quite acceptable
Pair<Long, Serializable> pair1 = getPropertyValue(value1);
Pair<Long, Serializable> pair2 = getPropertyValue(value2);
Pair<Long, Serializable> pair3 = getPropertyValue(value3);
if (pair1 == null || pair2 == null || pair3 == null)
{
// None of the values exist so no unique context values can exist
return null;
}
Long id1 = pair1.getFirst();
Long id2 = pair2.getFirst();
Long id3 = pair3.getFirst();
PropertyUniqueContextEntity entity = getPropertyUniqueContextByValues(id1, id2, id3);
// Done
if (logger.isDebugEnabled())
{
logger.debug(
"Searched for unique property context: \n" +
" Values: " + value1 + "-" + value2 + "-" + value3 + "\n" +
" Result: " + entity);
}
return entity == null ? null : entity.getId();
}
public void updatePropertyUniqueContext(Long id, Serializable value1, Serializable value2, Serializable value3)
{
// Translate the properties. Null values are acceptable
Long id1 = getOrCreatePropertyValue(value1).getFirst();
Long id2 = getOrCreatePropertyValue(value2).getFirst();
Long id3 = getOrCreatePropertyValue(value3).getFirst();
try
{
PropertyUniqueContextEntity entity = getPropertyUniqueContextById(id);
if (entity == null)
{
throw new DataIntegrityViolationException("No unique property context exists for id: " + id);
}
entity.setValue1PropId(id1);
entity.setValue2PropId(id2);
entity.setValue3PropId(id3);
updatePropertyUniqueContext(entity);
// Done
if (logger.isDebugEnabled())
{
logger.debug(
"Updated unique property context: \n" +
" ID: " + id + "\n" +
" Values: " + value1 + "-" + value2 + "-" + value3);
}
return;
}
catch (Throwable e)
{
throw new PropertyUniqueConstraintViolation(value1, value2, value3);
}
}
protected abstract PropertyUniqueContextEntity createPropertyUniqueContext(Long valueId1, Long valueId2, Long valueId3);
protected abstract PropertyUniqueContextEntity getPropertyUniqueContextById(Long id);
protected abstract PropertyUniqueContextEntity getPropertyUniqueContextByValues(Long valueId1, Long valueId2, Long valueId3);
protected abstract PropertyUniqueContextEntity updatePropertyUniqueContext(PropertyUniqueContextEntity entity);
//================================
// Utility methods
//================================
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Serializable convertPropertyIdSearchRows(List<PropertyIdSearchRow> rows) public Serializable convertPropertyIdSearchRows(List<PropertyIdSearchRow> rows)
{ {

View File

@@ -0,0 +1,120 @@
/*
* 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;
/**
* Entity bean for <b>alf_prop_unique_ctx</b> table.
*
* @author Derek Hulley
* @since 3.2
*/
public class PropertyUniqueContextEntity
{
private Long id;
private short version;
private Long value1PropId;
private Long value2PropId;
private Long value3PropId;
public PropertyUniqueContextEntity()
{
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(512);
sb.append("PropertyRootEntity")
.append("[ ID=").append(id)
.append(", version=").append(version)
.append(", value1PropId=").append(value1PropId)
.append(", value2PropId=").append(value2PropId)
.append(", value3PropId=").append(value3PropId)
.append("]");
return sb.toString();
}
public void incrementVersion()
{
if (version >= Short.MAX_VALUE)
{
this.version = 0;
}
else
{
this.version++;
}
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public short getVersion()
{
return version;
}
public void setVersion(short version)
{
this.version = version;
}
public Long getValue1PropId()
{
return value1PropId;
}
public void setValue1PropId(Long value1PropId)
{
this.value1PropId = value1PropId;
}
public Long getValue2PropId()
{
return value2PropId;
}
public void setValue2PropId(Long value2PropId)
{
this.value2PropId = value2PropId;
}
public Long getValue3PropId()
{
return value3PropId;
}
public void setValue3PropId(Long value3PropId)
{
this.value3PropId = value3PropId;
}
}

View File

@@ -29,6 +29,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import org.alfresco.repo.domain.CrcHelper; import org.alfresco.repo.domain.CrcHelper;
import org.alfresco.repo.props.PropertyUniqueConstraintViolation;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
@@ -255,6 +256,33 @@ public interface PropertyValueDAO
*/ */
void deleteProperty(Long id); void deleteProperty(Long id);
//================================
// 'alf_prop_unique_ctx' accessors
//================================
/**
* <b>alf_prop_unique_ctx</b> accessor: find an existing unique context.
* <p/>
* The DAO ensures that the region-context-value combination will be globally unique.
*
* @throws PropertyUniqueConstraintViolation if the combination is not unique
*/
Long createPropertyUniqueContext(Serializable value1, Serializable value2, Serializable value3);
/**
* @see #createPropertyUniqueContext(Serializable, Serializable, Serializable)
*/
Long getPropertyUniqueContext(Serializable value1, Serializable value2, Serializable value3);
/**
* @see #createPropertyUniqueContext(Serializable, Serializable, Serializable)
*/
void updatePropertyUniqueContext(Long id, Serializable value1, Serializable value2, Serializable value3);
/**
* @see #createPropertyUniqueContext(Serializable, Serializable, Serializable)
*/
void deletePropertyUniqueContext(Long id);
//================================
// Utility methods
//================================
/** /**
* Utility method to convert property query results into the original value. Note * Utility method to convert property query results into the original value. Note
* that the rows must all share the same root property ID. * that the rows must all share the same root property ID.

View File

@@ -26,11 +26,9 @@ package org.alfresco.repo.domain.propval;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@@ -38,11 +36,13 @@ import javax.naming.CompositeName;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.alfresco.repo.props.PropertyUniqueConstraintViolation;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID;
import org.alfresco.util.ISO8601DateFormat; import org.alfresco.util.ISO8601DateFormat;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
@@ -589,29 +589,29 @@ public class PropertyValueDAOTest extends TestCase
assertEquals(list, entityValueCheck); assertEquals(list, entityValueCheck);
} }
public void testProperty_UpdateToVersionRollover() throws Exception // public void testProperty_UpdateToVersionRollover() throws Exception
{ // {
final List<String> list = Collections.emptyList(); // final List<String> list = Collections.emptyList();
final Long propId = runPropertyTest((Serializable)list); // final Long propId = runPropertyTest((Serializable)list);
//
// Do 1000 updates to a property // // Do 1000 updates to a property
RetryingTransactionCallback<Void> updateThousandsCallback = new RetryingTransactionCallback<Void>() // RetryingTransactionCallback<Void> updateThousandsCallback = new RetryingTransactionCallback<Void>()
{ // {
public Void execute() throws Throwable // public Void execute() throws Throwable
{ // {
for (int i = 0; i < 1000; i++) // for (int i = 0; i < 1000; i++)
{ // {
propertyValueDAO.updateProperty(propId, (Serializable)list); // propertyValueDAO.updateProperty(propId, (Serializable)list);
} // }
return null; // return null;
} // }
}; // };
for (int i = 0; i < (Short.MAX_VALUE / 1000 + 1); i++) // for (int i = 0; i < (Short.MAX_VALUE / 1000 + 1); i++)
{ // {
txnHelper.doInTransaction(updateThousandsCallback, false); // txnHelper.doInTransaction(updateThousandsCallback, false);
} // }
} // }
//
public void testProperty_Delete() throws Exception public void testProperty_Delete() throws Exception
{ {
final ArrayList<String> list = new ArrayList<String>(20); final ArrayList<String> list = new ArrayList<String>(20);
@@ -681,4 +681,63 @@ public class PropertyValueDAOTest extends TestCase
removeCaches(); removeCaches();
testPropertySerializableValue(); testPropertySerializableValue();
} }
public void testPropertyUniqueContext() throws Exception
{
final String aaa = GUID.generate();
final String bbb = GUID.generate();
RetryingTransactionCallback<Void> testCallback = new RetryingTransactionCallback<Void>()
{
public Void execute() throws Throwable
{
// Get the ID for nulls
Long nullId = propertyValueDAO.getPropertyUniqueContext(null, null, null);
if (nullId != null)
{
propertyValueDAO.deletePropertyUniqueContext(nullId);
}
// Check nulls
propertyValueDAO.createPropertyUniqueContext(null, null, null);
try
{
propertyValueDAO.createPropertyUniqueContext(null, null, null);
fail("Failed to throw exception creating duplicate property unique context");
}
catch (PropertyUniqueConstraintViolation e)
{
// Expected
}
Long id = propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa);
try
{
propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa);
fail("Failed to throw exception creating duplicate property unique context");
}
catch (PropertyUniqueConstraintViolation e)
{
// Expected
}
// Now update it
propertyValueDAO.updatePropertyUniqueContext(id, "A", "AA", bbb);
// Should be able to create the previous one ...
propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa);
// ... and fail to create the second one
try
{
propertyValueDAO.createPropertyUniqueContext("A", "AA", bbb);
fail("Failed to throw exception creating duplicate property unique context");
}
catch (PropertyUniqueConstraintViolation e)
{
// Expected
}
// Delete
propertyValueDAO.deletePropertyUniqueContext(id);
propertyValueDAO.createPropertyUniqueContext("A", "AA", bbb);
return null;
}
};
txnHelper.doInTransaction(testCallback, false);
}
} }

View File

@@ -38,6 +38,7 @@ import org.alfresco.repo.domain.propval.PropertyRootEntity;
import org.alfresco.repo.domain.propval.PropertySerializableValueEntity; import org.alfresco.repo.domain.propval.PropertySerializableValueEntity;
import org.alfresco.repo.domain.propval.PropertyStringQueryEntity; import org.alfresco.repo.domain.propval.PropertyStringQueryEntity;
import org.alfresco.repo.domain.propval.PropertyStringValueEntity; import org.alfresco.repo.domain.propval.PropertyStringValueEntity;
import org.alfresco.repo.domain.propval.PropertyUniqueContextEntity;
import org.alfresco.repo.domain.propval.PropertyValueEntity; import org.alfresco.repo.domain.propval.PropertyValueEntity;
import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType; import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
@@ -81,6 +82,13 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
private static final String INSERT_PROPERTY_ROOT = "alfresco.propval.insert_PropertyRoot"; private static final String INSERT_PROPERTY_ROOT = "alfresco.propval.insert_PropertyRoot";
private static final String UPDATE_PROPERTY_ROOT = "alfresco.propval.update_PropertyRoot"; private static final String UPDATE_PROPERTY_ROOT = "alfresco.propval.update_PropertyRoot";
private static final String DELETE_PROPERTY_ROOT_BY_ID = "alfresco.propval.delete_PropertyRootById"; private static final String DELETE_PROPERTY_ROOT_BY_ID = "alfresco.propval.delete_PropertyRootById";
private static final String SELECT_PROPERTY_UNIQUE_CTX_BY_ID = "alfresco.propval.select_PropertyUniqueContextById";
private static final String SELECT_PROPERTY_UNIQUE_CTX_BY_VALUES = "alfresco.propval.select_PropertyUniqueContextByValues";
private static final String INSERT_PROPERTY_UNIQUE_CTX = "alfresco.propval.insert_PropertyUniqueContext";
private static final String UPDATE_PROPERTY_UNIQUE_CTX = "alfresco.propval.update_PropertyUniqueContext";
private static final String DELETE_PROPERTY_UNIQUE_CTX_BY_ID = "alfresco.propval.delete_PropertyUniqueContextById";
private static final String INSERT_PROPERTY_LINK = "alfresco.propval.insert_PropertyLink"; private static final String INSERT_PROPERTY_LINK = "alfresco.propval.insert_PropertyLink";
private static final String DELETE_PROPERTY_LINKS_BY_ROOT_ID = "alfresco.propval.delete_PropertyLinksByRootId"; private static final String DELETE_PROPERTY_LINKS_BY_ROOT_ID = "alfresco.propval.delete_PropertyLinksByRootId";
@@ -478,6 +486,53 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
template.delete(DELETE_PROPERTY_ROOT_BY_ID, entity); template.delete(DELETE_PROPERTY_ROOT_BY_ID, entity);
} }
@Override
protected PropertyUniqueContextEntity createPropertyUniqueContext(Long valueId1, Long valueId2, Long valueId3)
{
PropertyUniqueContextEntity entity = new PropertyUniqueContextEntity();
entity.setValue1PropId(valueId1);
entity.setValue2PropId(valueId2);
entity.setValue3PropId(valueId3);
Long id = (Long) template.insert(INSERT_PROPERTY_UNIQUE_CTX, entity);
entity.setId(id);
return entity;
}
@Override
protected PropertyUniqueContextEntity getPropertyUniqueContextById(Long id)
{
PropertyUniqueContextEntity entity = new PropertyUniqueContextEntity();
entity.setId(id);
entity = (PropertyUniqueContextEntity) template.queryForObject(SELECT_PROPERTY_UNIQUE_CTX_BY_ID, entity);
return entity;
}
@Override
protected PropertyUniqueContextEntity getPropertyUniqueContextByValues(Long valueId1, Long valueId2, Long valueId3)
{
PropertyUniqueContextEntity entity = new PropertyUniqueContextEntity();
entity.setValue1PropId(valueId1);
entity.setValue2PropId(valueId2);
entity.setValue3PropId(valueId3);
entity = (PropertyUniqueContextEntity) template.queryForObject(SELECT_PROPERTY_UNIQUE_CTX_BY_VALUES, entity);
return entity;
}
@Override
protected PropertyUniqueContextEntity updatePropertyUniqueContext(PropertyUniqueContextEntity entity)
{
entity.incrementVersion();
template.update(UPDATE_PROPERTY_UNIQUE_CTX, entity, 1);
return entity;
}
public void deletePropertyUniqueContext(Long id)
{
PropertyUniqueContextEntity entity = new PropertyUniqueContextEntity();
entity.setId(id);
template.delete(DELETE_PROPERTY_UNIQUE_CTX_BY_ID, entity);
}
@Override @Override
protected void createPropertyLink( protected void createPropertyLink(
Long rootPropId, Long rootPropId,

View File

@@ -0,0 +1,67 @@
/*
* 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.props;
import java.io.Serializable;
import org.alfresco.error.AlfrescoRuntimeException;
/**
* Exception generated when the {@link PropertyValueDAO}
*
* @author Derek Hulley
* @since 3.2
*/
public class PropertyUniqueConstraintViolation extends AlfrescoRuntimeException
{
private static final long serialVersionUID = -7792036870731759068L;
private final Serializable value1;
private final Serializable value2;
private final Serializable value3;
public PropertyUniqueConstraintViolation(Serializable value1, Serializable value2, Serializable value3)
{
super("Non-unique values for unique constraint: " + value1 + "-" + value2 + "-" + value3);
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
}
public Serializable getValue1()
{
return value1;
}
public Serializable getValue2()
{
return value2;
}
public Serializable getValue3()
{
return value3;
}
}