diff --git a/entity/Activity_entity/recordcontainers/db/onDBDelete.js b/entity/Activity_entity/recordcontainers/db/onDBDelete.js
index 0b4ab0d79b9ffb3e4d312560e84718ab38e2aa88..a50bce1e44d7fa89abbb2605ae42e8ba3092fb9b 100644
--- a/entity/Activity_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Activity_entity/recordcontainers/db/onDBDelete.js
@@ -1,3 +1,10 @@
+import("Context_lib");
+import("system.vars");
 import("Sql_lib");
+import("Attribute_lib");
 
-newWhere("ACTIVITYLINK.ACTIVITY_ID", "$field.ACTIVITYID").deleteData();
\ No newline at end of file
+newWhere("ACTIVITYLINK.ACTIVITY_ID", "$field.ACTIVITYID").deleteData();
+
+new AttributeRelationQuery(vars.get("$field.ACTIVITYID"), null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
+    
\ No newline at end of file
diff --git a/entity/Campaign_entity/recordcontainers/db/onDBDelete.js b/entity/Campaign_entity/recordcontainers/db/onDBDelete.js
index 8c3db7d4887c574724a66fa0753364218a868324..4a47111a898384fe8d3ace4bca27a742ff1406a1 100644
--- a/entity/Campaign_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Campaign_entity/recordcontainers/db/onDBDelete.js
@@ -1,6 +1,8 @@
+import("Context_lib");
 import("system.db");
 import("system.vars");
 import("Sql_lib");
+import("Attribute_lib");
 
 var currentId = vars.getString("$field.CAMPAIGNID");
 
@@ -19,4 +21,7 @@ if (currentId)
     });
     
     db.deletes(toDelete);
-}
\ No newline at end of file
+}
+
+new AttributeRelationQuery(currentId, null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/entity/Contract_entity/Contract_entity.aod b/entity/Contract_entity/Contract_entity.aod
index 03b96e6d6e75c962645b70676733e242c5743943..6608690641cf1da4201220b3c1421d43d5e17784 100644
--- a/entity/Contract_entity/Contract_entity.aod
+++ b/entity/Contract_entity/Contract_entity.aod
@@ -384,6 +384,7 @@
       <fromClauseProcess>%aditoprj%/entity/Contract_entity/recordcontainers/db/fromClauseProcess.js</fromClauseProcess>
       <conditionProcess>%aditoprj%/entity/Contract_entity/recordcontainers/db/conditionProcess.js</conditionProcess>
       <orderClauseProcess>%aditoprj%/entity/Contract_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess>
+      <onDBDelete>%aditoprj%/entity/Contract_entity/recordcontainers/db/onDBDelete.js</onDBDelete>
       <linkInformation>
         <linkInformation>
           <name>78925203-f1c5-4e7e-9424-1a23500c655d</name>
diff --git a/entity/Contract_entity/recordcontainers/db/onDBDelete.js b/entity/Contract_entity/recordcontainers/db/onDBDelete.js
new file mode 100644
index 0000000000000000000000000000000000000000..b9de11647b14efdc5b1651b28193052a84998710
--- /dev/null
+++ b/entity/Contract_entity/recordcontainers/db/onDBDelete.js
@@ -0,0 +1,6 @@
+import("system.vars");
+import("Context_lib");
+import("Attribute_lib");
+
+new AttributeRelationQuery(vars.get("$field.CONTRACTID"), null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js b/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js
index a5b405bd03814af4c9bd758e5db8d0329200cf60..8ecca18f87ccd7a2c0c473cd8e3b3087d8a55342 100644
--- a/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/DocumentTemplate_entity/recordcontainers/db/onDBDelete.js
@@ -1,10 +1,15 @@
+import("Context_lib");
 import("Sql_lib");
 import("system.vars");
 import("system.db");
+import("Attribute_lib");
 
 var binaryId = newSelect("ID", SqlUtils.getBinariesAlias())
                     .from("ASYS_BINARIES")
                     .where("ASYS_BINARIES.ROW_ID", "$field.DOCUMENTTEMPLATEID")
                     .cell();
 if (binaryId)
-    db.deleteBinary(binaryId, SqlUtils.getBinariesAlias());
\ No newline at end of file
+    db.deleteBinary(binaryId, SqlUtils.getBinariesAlias());
+
+new AttributeRelationQuery(vars.get("$field.DOCUMENTTEMPLATEID"), null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/entity/Employee_entity/Employee_entity.aod b/entity/Employee_entity/Employee_entity.aod
index dd20915b9f3a31053421416f69e276e664a507e2..ca9331355b1030eca6a28166522a70d87e1fd6a0 100644
--- a/entity/Employee_entity/Employee_entity.aod
+++ b/entity/Employee_entity/Employee_entity.aod
@@ -363,6 +363,7 @@
       <name>jdito</name>
       <jDitoRecordAlias>Data_alias</jDitoRecordAlias>
       <isFilterable v="true" />
+      <isRequireContainerFiltering v="true" />
       <isSortable v="true" />
       <contentProcess>%aditoprj%/entity/Employee_entity/recordcontainers/jdito/contentProcess.js</contentProcess>
       <onInsert>%aditoprj%/entity/Employee_entity/recordcontainers/jdito/onInsert.js</onInsert>
diff --git a/entity/Employee_entity/recordcontainers/jdito/contentProcess.js b/entity/Employee_entity/recordcontainers/jdito/contentProcess.js
index d5f8e7904ab14664284c2e53511be8a05485bc44..78bae2c27e11814875466e02b79032ce7acf4ef2 100644
--- a/entity/Employee_entity/recordcontainers/jdito/contentProcess.js
+++ b/entity/Employee_entity/recordcontainers/jdito/contentProcess.js
@@ -1,3 +1,4 @@
+import("system.logging");
 import("Sql_lib");
 import("system.db");
 import("Attribute_lib");
@@ -7,7 +8,7 @@ import("system.tools");
 import("Util_lib");
 import("Contact_lib");
 import("JditoFilter_lib");
-import("Employee_lib");
+import("Employee_lib");attrib
 
 var users;
 if (vars.exists("$local.idvalues") && vars.get("$local.idvalues"))
@@ -43,7 +44,7 @@ users = users.map(function (user)
 var filter = vars.get("$local.filter"); 
 
 //TODO: this is a workaround that filters the records manually, it should be possible to filter the users with a tools.* method
-var filterFields = ["UID", "TITLE", "ISACTIVE", "FIRSTNAME", "LASTNAME", "EMAIL_ADDRESS", "", "DESCRIPTION", "CONTACT_ID", "DEPARTMENT", "", "", "ROLE_FILTER"];
+var filterFields = ["UID", "TITLE", "ISACTIVE", "FIRSTNAME", "LASTNAME", "EMAIL_ADDRESS", "", "DESCRIPTION", "CONTACT_ID", "DEPARTMENT", "", "", "ROLE_FILTER", "$$$LOOKUPFIELD$$$"];
 var filterFns = {
     "ROLE_FILTER" : function (pRecordVal, pFilterVal, pOperator)
     {
@@ -62,8 +63,20 @@ var filterFns = {
             default:
                 return false;
         }
+    },
+    "$$$LOOKUPFIELD$$$" : function (pRecordValue, pFilterValue, pOperator, pRow)
+    {
+        if (pOperator == "CONTAINS")
+        {
+            return pRow.some(function (fieldValue)
+            {
+                return (new RegExp(pFilterValue, "i")).test(fieldValue);
+            });
+        }
+        return false;
     }
 };
+logging.log(JSON.stringify(filter, null, "\t"))
 users = JditoFilterUtils.filterRecords(filterFields, users, filter.filter, filterFns);
 
 users.forEach(function (user) {user[12] = "";}); //clean up the ROLE_FILTER field, we don't need it after filtering
diff --git a/entity/Employee_entity/recordcontainers/jdito/onDelete.js b/entity/Employee_entity/recordcontainers/jdito/onDelete.js
index ab759edc01f99d49bbc901935e5d0805b54cfe10..05394e349deb777b797db46b0925d4e47f831d67 100644
--- a/entity/Employee_entity/recordcontainers/jdito/onDelete.js
+++ b/entity/Employee_entity/recordcontainers/jdito/onDelete.js
@@ -1,3 +1,5 @@
+import("Context_lib");
+import("Attribute_lib");
 import("system.neon");
 import("system.vars");
 import("system.tools");
@@ -5,4 +7,9 @@ import("Employee_lib");
 
 //the current user should not delete himself
 if (EmployeeUtils.getCurrentUserName() != vars.get("$field.TITLE") && !EmployeeUtils.hasRelations(vars.get("$field.CONTACT_ID")))
-    tools.deleteUser(vars.get("$field.TITLE"));
\ No newline at end of file
+{
+    tools.deleteUser(vars.get("$field.TITLE"));
+    
+    AttributeRelationQuery(EmployeeUtils.sliceUserId(vars.get("$field.UID")), null, ContextUtils.getCurrentContextId())
+        .deleteAllAttributes();
+}
\ No newline at end of file
diff --git a/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js b/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js
index 541e655e366ce0336ba70969c703bb67dcbe8d1b..7fc0b527fdceab78d1a224caf8c8229fcb5e03a4 100644
--- a/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Leadimport_entity/recordcontainers/db/onDBDelete.js
@@ -1,6 +1,8 @@
+import("Context_lib");
 import("Sql_lib");
 import("system.vars");
 import("system.db");
+import("Attribute_lib");
 
 var leadImportId = vars.getString("$field.LEADIMPORTID");
 
@@ -22,14 +24,16 @@ newSelect("LEADLOGID")
 
 if(leadImportId != "")//delete the connected importfields
 {
-    db.deleteData("IMPORTFIELD", newWhere("IMPORTFIELD.LEADIMPORT_ID", leadImportId).build());
-    db.deleteData("LEADTEMP", newWhere("LEADTEMP.ROW_ID", leadImportId).build());
-    db.deleteData("LEAD", newWhere("LEAD.LEADIMPORT_ID", leadImportId).build());
-    db.deleteData("LEADLOG", newWhere("LEADLOG.LEADIMPORT_ID", leadImportId).build());
+    newWhere("IMPORTFIELD.LEADIMPORT_ID", leadImportId).deleteData();
+    newWhere("LEADTEMP.ROW_ID", leadImportId).deleteData();
+    newWhere("LEAD.LEADIMPORT_ID", leadImportId).deleteData();
+    newWhere("LEADLOG.LEADIMPORT_ID", leadImportId).deleteData();
 }
 
 binMetadata.forEach(function(pMeta) 
 { //delete the connected binData
     db.deleteBinary(pMeta.id, SqlUtils.getBinariesAlias());
 });
-    
\ No newline at end of file
+
+new AttributeRelationQuery(leadImportId, null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/entity/Offer_entity/recordcontainers/db/onDBDelete.js b/entity/Offer_entity/recordcontainers/db/onDBDelete.js
index dbcf3083e10d4f8e2686a00a91f238d27e33c1f1..1e1ad63fd5ccb8c6fa1a56dc2c313247474d34fb 100644
--- a/entity/Offer_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Offer_entity/recordcontainers/db/onDBDelete.js
@@ -1,9 +1,14 @@
+import("Context_lib");
 import("Workflow_lib");
 import("Sql_lib");
 import("system.vars");
+import("Attribute_lib");
 
 newWhere("OFFERITEM.OFFER_ID", "$field.OFFERID")
     .deleteData();
     
+new AttributeRelationQuery(vars.get("$field.OFFERID"), null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
+    
 WorkflowStarter.deleted({sum : Number(vars.get("$field.TotalGross")), status : vars.get("$field.STATUS")});
 WorkflowSignalSender.deleted();
\ No newline at end of file
diff --git a/entity/Order_entity/recordcontainers/db/onDBDelete.js b/entity/Order_entity/recordcontainers/db/onDBDelete.js
index 78799f19269dee9332c2bf22d10e8247b889c132..9d21e312247e4be629915bcebe2e0f1e489457a3 100644
--- a/entity/Order_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Order_entity/recordcontainers/db/onDBDelete.js
@@ -1,3 +1,9 @@
+import("Context_lib");
+import("system.vars");
 import("Sql_lib");
+import("Attribute_lib");
 
-newWhere("SALESORDERITEM.SALESORDER_ID", "$field.SALESORDERID").deleteData();
\ No newline at end of file
+newWhere("SALESORDERITEM.SALESORDER_ID", "$field.SALESORDERID").deleteData();
+
+new AttributeRelationQuery(vars.get("$field.SALESORDERID"), null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/entity/Organisation_entity/recordcontainers/db/onDBDelete.js b/entity/Organisation_entity/recordcontainers/db/onDBDelete.js
index b40a056ac00e3fec5cff3d5b2f52df957c0a5584..8ee5af70d3b5bff479cd64e4e16db0fb2542d6ee 100644
--- a/entity/Organisation_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Organisation_entity/recordcontainers/db/onDBDelete.js
@@ -1,10 +1,15 @@
+import("Context_lib");
 import("Workflow_lib");
 import("system.vars");
 import("DuplicateScanner_lib");
+import("Attribute_lib");
 
 // TODO: enable when duplicate-module is finalized
 let contactId = vars.get("$field.CONTACTID");
 DuplicateScannerUtils.DeleteCachedDuplicate(contactId);
 
+new AttributeRelationQuery(contactId, null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
+
 //WorkflowStarter.deleted();
 //WorkflowSignalSender.deleted();
\ No newline at end of file
diff --git a/entity/Person_entity/recordcontainers/db/onDBDelete.js b/entity/Person_entity/recordcontainers/db/onDBDelete.js
index 961f7f520c417062146000eefd6a1f684683568d..85ede0d4e7b00eff43445e5906725a325ef1cedd 100644
--- a/entity/Person_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Person_entity/recordcontainers/db/onDBDelete.js
@@ -1,3 +1,5 @@
+import("Context_lib");
+import("Attribute_lib");
 import("Workflow_lib");
 import("system.vars");
 import("DuplicateScanner_lib");
@@ -5,5 +7,8 @@ import("DuplicateScanner_lib");
 let contactId = vars.get("$field.CONTACTID");
 DuplicateScannerUtils.DeleteCachedDuplicate(contactId);
 
+new AttributeRelationQuery(contactId, null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
+
 //WorkflowStarter.deleted();
 //WorkflowSignalSender.deleted();
\ No newline at end of file
diff --git a/entity/Product_entity/recordcontainers/db/onDBDelete.js b/entity/Product_entity/recordcontainers/db/onDBDelete.js
index 9fe9dbd2473b9f99b08619e247c6f4ab22acabaa..0ab63616f119ad19dc5a9318f42cfd7eab6524d6 100644
--- a/entity/Product_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Product_entity/recordcontainers/db/onDBDelete.js
@@ -1,4 +1,6 @@
+import("Context_lib");
 import("Sql_lib");
+import("Attribute_lib");
 
 newWhereIfSet("PROD2PROD.DEST_ID", "$field.PRODUCTID")
     .deleteData();
@@ -10,4 +12,7 @@ newWhereIfSet("PRODUCTPRICE.PRODUCT_ID", "$field.PRODUCTID")
     .deleteData();
     
 newWhereIfSet("STOCK.PRODUCT_ID", "$field.PRODUCTID")
-    .deleteData();
\ No newline at end of file
+    .deleteData();
+    
+new AttributeRelationQuery(productId, null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js b/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js
index 050a3e6b0da0d33875135bd9c1c8f5cb40503737..bdeb6b5340b8ac62e3f9330b5a14367ee687593e 100644
--- a/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/Salesproject_entity/recordcontainers/db/onDBDelete.js
@@ -3,6 +3,7 @@ import("Context_lib");
 import("system.db");
 import("system.vars");
 import("Sql_lib");
+import("Attribute_lib");
 
 var currentId = vars.getString("$field.SALESPROJECTID");
 
@@ -42,4 +43,7 @@ if (currentId)
 // TODO: auch Dokumente, Aktivitäten, Aufgaben, Zeiterfassungen löschen?
 }
 
+new AttributeRelationQuery(currentId, null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
+
 WorkflowStarter.deleted();
\ No newline at end of file
diff --git a/entity/SupportTicket_entity/SupportTicket_entity.aod b/entity/SupportTicket_entity/SupportTicket_entity.aod
index 6a47734f54f374d06e5eb8981c3842ff51f00751..90581faffeffc21f276ddf139aee0e0d3f57266f 100644
--- a/entity/SupportTicket_entity/SupportTicket_entity.aod
+++ b/entity/SupportTicket_entity/SupportTicket_entity.aod
@@ -405,6 +405,7 @@
       <conditionProcess>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/conditionProcess.js</conditionProcess>
       <orderClauseProcess>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/orderClauseProcess.js</orderClauseProcess>
       <onDBInsert>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/onDBInsert.js</onDBInsert>
+      <onDBDelete>%aditoprj%/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js</onDBDelete>
       <linkInformation>
         <linkInformation>
           <name>512c662b-33f6-4491-bd24-a8b862f2de84</name>
diff --git a/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js b/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js
index 03335cb841ab9bc3075360dc349f3fcd6338eeec..607773386a086a99f8815eeace21e53f453fb85d 100644
--- a/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js
+++ b/entity/SupportTicket_entity/recordcontainers/db/onDBDelete.js
@@ -1,3 +1,9 @@
+import("Context_lib");
+import("system.vars");
+import("Attribute_lib");
 import("Sql_lib");
 
-newWhereIfSet("TASKLINK.TASK_ID", "$field.TASK_TASKID").deleteData();
\ No newline at end of file
+newWhereIfSet("TASKLINK.TASK_ID", "$field.TASK_TASKID").deleteData();
+
+new AttributeRelationQuery(vars.get("$field.TICKETID"), null, ContextUtils.getCurrentContextId())
+    .deleteAllAttributes();
\ No newline at end of file
diff --git a/process/Attribute_lib/process.js b/process/Attribute_lib/process.js
index 04bbeaf9cff3ad1af1ae13cb7e8890acd31df2c4..c38845e81d7c4b72931a90084071a9e5dda027a5 100644
--- a/process/Attribute_lib/process.js
+++ b/process/Attribute_lib/process.js
@@ -1301,7 +1301,7 @@ AttributeRelationQuery.prototype.includeDisplayValue = function ()
 /**
  * Executes the query and returns the result, depending on the properties of the AttributeRelationQuery object.
  * 
- * @return {Object[]} Array of objects. By default, the objects contain the properties {attributeId, value, attributeRelationId, attributeName, attributeType}.
+ * @return {AttributeRelation[]} Array of objects. By default, the objects contain the properties {attributeId, value, attributeRelationId, attributeName, attributeType}.
  *      If includeDisplayValue is true, the object also contains the property 'displayValue' and if includeFullAttributeName is true, there is also the property
  *      'fullAttributeName'.
  */
@@ -1313,7 +1313,9 @@ AttributeRelationQuery.prototype.getAttributes = function ()
         "AB_ATTRIBUTE.ATTRIBUTE_NAME",
         "COMBOVAL.ATTRIBUTE_NAME",
         "AB_ATTRIBUTE.AB_ATTRIBUTEID",
-        "AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID"
+        "AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID",
+        "AB_ATTRIBUTERELATION.OBJECT_ROWID",
+        "AB_ATTRIBUTERELATION.OBJECT_TYPE"
     ];
     
     var valueFields = AttributeTypeUtil.getAllDatabaseFields();
@@ -1328,13 +1330,7 @@ AttributeRelationQuery.prototype.getAttributes = function ()
     
     var mappingFn = function (row)
     {
-        var attrObj = {
-            attributeId : row[4],
-            value : row[AttributeTypeUtil.getTypeColumnIndex(row[0]) + defaultFields.length],
-            attributeRelationId : row[5],
-            attributeName : row[2],
-            attributeType : row[0]
-        };
+        var attrObj = new AttributeRelation(row[5], row[4], row[AttributeTypeUtil.getTypeColumnIndex(row[0]) + defaultFields.length], row[2], row[0], row[6], row[7]);
         
         if (this._includeDisplayValue)
         {
@@ -1355,7 +1351,7 @@ AttributeRelationQuery.prototype.getAttributes = function ()
 }
 
 /**
- * @return {Object}
+ * @return {AttributeRelation}
  */
 AttributeRelationQuery.prototype.getSingleAttribute = function ()
 {
@@ -1442,13 +1438,98 @@ AttributeRelationQuery.prototype.insertAttribute = function (pValue, pOmitValida
 
 /**
  * deletes all attribute relations with the given rowId and objectType
+ * 
+ * @return {Number} count of deleted rows
  */
 AttributeRelationQuery.prototype.deleteAllAttributes = function ()
 {
     if (!this._rowId)
         throw new Error("AttributeRelationQuery: Row id is required for delete");
     
-    newWhere("AB_ATTRIBUTERELATION.OBJECT_ROWID", this._rowId)
-        .andIfSet("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", this._objectType)
+    return newWhere("AB_ATTRIBUTERELATION.OBJECT_ROWID", this._rowId)
+        .andIfSet("AB_ATTRIBUTERELATION.OBJECT_TYPE", this._objectType)
         .deleteData();
+}
+
+/**
+ * Object representing one attribute relation in the database. Don't use this constructor in you own code!
+ * Instances of this should only be created by functions in this library.
+ * 
+ * @param {String} pAttributeRelationId attribute relation id
+ * @param {String} pAttributeId attribute id
+ * @param {String} pValue value of the attribute
+ * @param {String} pAttributeName name of the attribute
+ * @param {String} pAttributeType type of the attribute
+ * @param {String} pObjectRowId rowId of the linked object
+ * @param {String} pObjectType context of the linked object
+ */
+function AttributeRelation (pAttributeRelationId, pAttributeId, pValue, pAttributeName, pAttributeType, pObjectRowId, pObjectType)
+{
+    if (!pAttributeRelationId)
+        throw new Error("AttributeRelation: pAttributeRelationId must be provided");
+        
+    this.attributeRelationId = pAttributeRelationId;
+    this.attributeId = pAttributeId;
+    this.value = pValue;
+    this.attributeName = pAttributeName;
+    this.attributeType = pAttributeType;
+    this.objectRowId = pObjectRowId;
+    this.objectType = pObjectType;
+    this.displayValue = undefined;
+    this.fullAttributeName = undefined;
+}
+
+/**
+ * updates the value of the attribute in the database
+ * 
+ * @param {String} pValue the new value of the attribute relation
+ * @return {Boolean} currently the function always returns true (if some kind of validation is implemented in the future, 
+ *      it will return false if the validation fails)
+ */
+AttributeRelation.prototype.updateAttribute = function (pValue)
+{
+    if (pValue == undefined || pValue == "")
+        throw new Error("AttributeRelation: no value provided for update");
+        
+    var attrData = {
+        "DATE_EDIT" : vars.get("$sys.date"),
+        "USER_EDIT" : vars.get("$sys.user")
+    };
+
+    var valueField = AttributeTypeUtil.getDatabaseField(this.attributeType);
+    if (valueField)
+        attrData[valueField] = pValue;
+
+    newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", this.attributeRelationId)
+        .updateFields(attrData);
+    return true;
+}
+
+/**
+ * deletes the attribute relation from the database
+ * 
+ * @param {Boolean} [pOmitValidation=false] if set to true, the function won't check if the min count prohibits the deletion
+ * @retun {Boolean} true if it was deleted and false if the min count doesn't allow the deletion
+ */
+AttributeRelation.prototype.deleteAttribute = function (pOmitValidation)
+{
+    if (!pOmitValidation)
+    {
+        var minCount = newSelect("MIN_COUNT")
+            .from("AB_ATTRIBUTEUSAGE")
+            .where("AB_ATTRIBUTEUSAGE.AB_ATTRIBUTE_ID", this.attributeId)
+            .and("AB_ATTRIBUTEUSAGE.OBJECT_TYPE", this.objectType)
+            .cell();
+
+        if (minCount && minCount != 0)
+        {
+            let timesUsed = new AttributeRelationQuery(this.objectRowId, this.attributeId, this.objectType).getAttributeCount();
+            if (timesUsed <= minCount)
+                return false;
+        }
+    }
+    
+    newWhere("AB_ATTRIBUTERELATION.AB_ATTRIBUTERELATIONID", this.attributeRelationId)
+        .deleteData();
+    return true;
 }
\ No newline at end of file