You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2018/08/27 22:25:23 UTC

[directory-ldap-api] branch master updated: Fixed the SchemaObject hashcode computation

This is an automated email from the ASF dual-hosted git repository.

elecharny pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/directory-ldap-api.git


The following commit(s) were added to refs/heads/master by this push:
     new 7a9c9ff  Fixed the SchemaObject hashcode computation
     new 3ac2712  Merge branch 'master' of https://gitbox.apache.org/repos/asf/directory-ldap-api
7a9c9ff is described below

commit 7a9c9ff074e1ade2ab2522941c2f7b9e8414db5c
Author: Emmanuel Lécharny <el...@symas.com>
AuthorDate: Tue Aug 28 00:25:01 2018 +0200

    Fixed the SchemaObject hashcode computation
---
 .../ldap/aci/protectedItem/RestrictedByItem.java   |   4 +-
 .../ldap/model/schema/AbstractSchemaObject.java    | 245 +++++++++------------
 .../api/ldap/model/schema/AttributeType.java       |   5 +-
 .../api/ldap/model/schema/DitContentRule.java      | 143 ++++++------
 .../api/ldap/model/schema/DitStructureRule.java    |  23 +-
 .../api/ldap/model/schema/LdapSyntax.java          |  20 +-
 .../ldap/model/schema/LoadableSchemaObject.java    |  14 +-
 .../api/ldap/model/schema/MatchingRule.java        |   1 +
 .../api/ldap/model/schema/MatchingRuleUse.java     |  31 +--
 .../ldap/model/schema/MutableAttributeType.java    | 140 ++++++------
 .../api/ldap/model/schema/MutableMatchingRule.java |  31 ++-
 .../api/ldap/model/schema/MutableObjectClass.java  | 159 +++++++------
 .../directory/api/ldap/model/schema/NameForm.java  |  80 +++----
 .../api/ldap/model/schema/ObjectClass.java         |   1 +
 .../api/ldap/model/schema/SchemaObject.java        |  16 --
 .../ldap/schema/loader/SchemaEntityFactory.java    |   6 -
 16 files changed, 424 insertions(+), 495 deletions(-)

diff --git a/ldap/extras/aci/src/main/java/org/apache/directory/api/ldap/aci/protectedItem/RestrictedByItem.java b/ldap/extras/aci/src/main/java/org/apache/directory/api/ldap/aci/protectedItem/RestrictedByItem.java
index 638261a..e831298 100644
--- a/ldap/extras/aci/src/main/java/org/apache/directory/api/ldap/aci/protectedItem/RestrictedByItem.java
+++ b/ldap/extras/aci/src/main/java/org/apache/directory/api/ldap/aci/protectedItem/RestrictedByItem.java
@@ -80,11 +80,11 @@ public class RestrictedByItem extends ProtectedItem
             {
                 if ( item != null )
                 {
-                    hash = hash * 17 + item.hashCode();
+                    hash = hash * item.hashCode();
                 }
                 else
                 {
-                    hash = hash * 17 + 37;
+                    hash = hash * 37;
                 }
             }
         }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AbstractSchemaObject.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AbstractSchemaObject.java
index b2e7b48..67fedfc 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AbstractSchemaObject.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AbstractSchemaObject.java
@@ -89,9 +89,6 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
     /** Whether or not this SchemaObject is enabled */
     protected boolean isEnabled = true;
 
-    /** Whether or not this SchemaObject can be modified */
-    protected boolean isReadOnly = false;
-
     /** Whether or not this SchemaObject is obsolete */
     protected boolean isObsolete = false;
 
@@ -114,7 +111,7 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
     protected volatile boolean locked;
 
     /** The hashcode for this schemaObject */
-    private int h;
+    protected volatile int h = 0;
 
 
     /**
@@ -130,6 +127,7 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
         this.oid = oid;
         extensions = new HashMap<>();
         names = new ArrayList<>();
+        computeHashCode();
     }
 
 
@@ -224,7 +222,7 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
 
     /**
      * Add a new name to the list of names for this SchemaObject. The name
-     * is lowercased and trimmed.
+     * is lower cased and trimmed.
      * 
      * @param namesToAdd The names to add
      */
@@ -236,31 +234,30 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            // We must avoid duplicated names, as names are case insensitive
-            Set<String> lowerNames = new HashSet<>();
+        // We must avoid duplicated names, as names are case insensitive
+        Set<String> lowerNames = new HashSet<>();
 
-            // Fills a set with all the existing names
-            for ( String name : this.names )
-            {
-                lowerNames.add( Strings.toLowerCaseAscii( name ) );
-            }
+        // Fills a set with all the existing names
+        for ( String name : this.names )
+        {
+            lowerNames.add( Strings.toLowerCaseAscii( name ) );
+        }
 
-            for ( String name : namesToAdd )
+        for ( String name : namesToAdd )
+        {
+            if ( name != null )
             {
-                if ( name != null )
+                String lowerName = Strings.toLowerCaseAscii( name );
+                // Check that the lower cased names is not already present
+                if ( !lowerNames.contains( lowerName ) )
                 {
-                    String lowerName = Strings.toLowerCaseAscii( name );
-                    // Check that the lower cased names is not already present
-                    if ( !lowerNames.contains( lowerName ) )
-                    {
-                        this.names.add( name );
-                        lowerNames.add( lowerName );
-                    }
+                    this.names.add( name );
+                    lowerNames.add( lowerName );
                 }
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -283,18 +280,17 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             return;
         }
 
-        if ( !isReadOnly )
-        {
-            this.names = new ArrayList<>( names.size() );
+        this.names = new ArrayList<>( names.size() );
 
-            for ( String name : names )
+        for ( String name : names )
+        {
+            if ( name != null )
             {
-                if ( name != null )
-                {
-                    this.names.add( name );
-                }
+                this.names.add( name );
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -316,18 +312,17 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             return;
         }
 
-        if ( !isReadOnly )
-        {
-            this.names.clear();
+        this.names.clear();
 
-            for ( String name : names )
+        for ( String name : names )
+        {
+            if ( name != null )
             {
-                if ( name != null )
-                {
-                    this.names.add( name );
-                }
+                this.names.add( name );
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -356,10 +351,9 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.description = description;
-        }
+        this.description = description;
+        
+        computeHashCode();
     }
 
 
@@ -388,10 +382,9 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.specification = specification;
-        }
+        this.specification = specification;
+        
+        computeHashCode();
     }
 
 
@@ -428,39 +421,14 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
     @Override
     public void setEnabled( boolean enabled )
     {
-        if ( !isReadOnly )
-        {
-            isEnabled = enabled;
-        }
-    }
-
-
-    /**
-     * Tells if this SchemaObject is ReadOnly.
-     * 
-     * @return true if the SchemaObject is not modifiable
-     */
-    @Override
-    public boolean isReadOnly()
-    {
-        return isReadOnly;
-    }
-
-
-    /**
-     * Sets the SchemaObject readOnly flag
-     * 
-     * @param readOnly The current SchemaObject ReadOnly status
-     */
-    @Override
-    public void setReadOnly( boolean readOnly )
-    {
         if ( locked )
         {
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        this.isReadOnly = readOnly;
+        isEnabled = enabled;
+        
+        computeHashCode();
     }
 
 
@@ -492,10 +460,9 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.isObsolete = obsolete;
-        }
+        this.isObsolete = obsolete;
+        
+        computeHashCode();
     }
 
 
@@ -557,17 +524,16 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            List<String> valueList = new ArrayList<>();
+        List<String> valueList = new ArrayList<>();
 
-            for ( String value : values )
-            {
-                valueList.add( value );
-            }
-
-            extensions.put( Strings.toUpperCaseAscii( key ), valueList );
+        for ( String value : values )
+        {
+            valueList.add( value );
         }
+
+        extensions.put( Strings.toUpperCaseAscii( key ), valueList );
+        
+        computeHashCode();
     }
 
 
@@ -584,10 +550,9 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            extensions.put( Strings.toUpperCaseAscii( key ), values );
-        }
+        extensions.put( Strings.toUpperCaseAscii( key ), values );
+        
+        computeHashCode();
     }
 
 
@@ -604,7 +569,7 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && ( extensions != null ) )
+        if ( extensions != null )
         {
             this.extensions = new HashMap<>();
 
@@ -620,6 +585,7 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
                 this.extensions.put( Strings.toUpperCaseAscii( entry.getKey() ), values );
             }
 
+            computeHashCode();
         }
     }
 
@@ -674,27 +640,9 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.schemaName = schemaName;
-        }
-    }
-
-
-    /**
-     * This method is final to forbid the inherited classes to implement
-     * it. This has been done for performances reasons : the hashcode should
-     * be computed only once, and stored locally.
-     * 
-     * The hashcode is currently computed in the lock() method, which is a hack
-     * that should be fixed.
-     * 
-     * @return {@inheritDoc}
-     */
-    @Override
-    public final int hashCode()
-    {
-        return h;
+        this.schemaName = schemaName;
+        
+        computeHashCode();
     }
 
 
@@ -835,11 +783,6 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             return false;
         }
 
-        if ( this.isReadOnly != that.isReadOnly )
-        {
-            return false;
-        }
-
         if ( this.description == null )
         {
             return that.description == null;
@@ -883,7 +826,6 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
         // copy the flags
         isEnabled = original.isEnabled();
         isObsolete = original.isObsolete();
-        isReadOnly = original.isReadOnly();
 
         // copy the names
         names = new ArrayList<>();
@@ -939,6 +881,18 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
 
         // Clear the names
         names.clear();
+        
+        computeHashCode();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public final void lock()
+    {
+        locked = true;
     }
 
 
@@ -949,56 +903,55 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
     {
         locked = false;
     }
-
-
+    
+    
     /**
-     * {@inheritDoc}
+     * Compute the hashcode, and store it in the 'h' variable
      */
-    @Override
-    public final void lock()
+    protected void computeHashCode()
     {
-        if ( locked )
-        {
-            return;
-        }
-
-        h = 37;
+        int hash = 37;
 
         // The OID
-        h += h * 17 + oid.hashCode();
+        if ( oid != null )
+        {
+            hash += hash * 17 + oid.hashCode();
+        }
 
         // The SchemaObject type
-        h += h * 17 + objectType.getValue();
+        if ( objectType != null )
+        {
+            hash += hash * 17 + objectType.getValue();
+        }
 
         // The Names, if any
         if ( ( names != null ) && !names.isEmpty() )
         {
             for ( String name : names )
             {
-                h += h * 17 + name.hashCode();
+                hash += hash * 17 + name.hashCode();
             }
         }
 
         // The schemaName if any
         if ( schemaName != null )
         {
-            h += h * 17 + schemaName.hashCode();
+            hash += hash * 17 + schemaName.hashCode();
         }
 
-        h += h * 17 + ( isEnabled ? 1 : 0 );
-        h += h * 17 + ( isReadOnly ? 1 : 0 );
+        hash += hash * 17 + ( isEnabled ? 1 : 0 );
 
         // The description, if any
         if ( description != null )
         {
-            h += h * 17 + description.hashCode();
+            hash += hash * 17 + description.hashCode();
         }
 
         // The extensions, if any
         for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
         {
             String key = entry.getKey();
-            h += h * 17 + key.hashCode();
+            hash += hash * 17 + key.hashCode();
 
             List<String> values = entry.getValue();
 
@@ -1006,11 +959,21 @@ public abstract class AbstractSchemaObject implements SchemaObject, Serializable
             {
                 for ( String value : values )
                 {
-                    h += h * 17 + value.hashCode();
+                    hash += hash * 17 + value.hashCode();
                 }
             }
         }
+        
+        h = hash;
+    }
 
-        locked = true;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int hashCode()
+    {
+        return h;
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java
index c7dc3cc..946586c 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java
@@ -186,6 +186,7 @@ public class AttributeType extends AbstractSchemaObject implements Cloneable
     public AttributeType( String oid )
     {
         super( SchemaObjectType.ATTRIBUTE_TYPE, oid );
+        computeHashCode();
     }
 
 
@@ -618,8 +619,8 @@ public class AttributeType extends AbstractSchemaObject implements Cloneable
 
         return copy;
     }
-
-
+    
+    
     /**
      * {@inheritDoc}
      */
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitContentRule.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitContentRule.java
index 1385a81..60c23b2 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitContentRule.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitContentRule.java
@@ -25,7 +25,6 @@ import java.util.List;
 
 import org.apache.directory.api.i18n.I18n;
 
-
 /**
  * A ditContentRule specification. ditContentRules identify the content of
  * entries of a particular structural objectClass. They specify the AUXILIARY
@@ -158,6 +157,7 @@ public class DitContentRule extends AbstractSchemaObject
         mustAttributeTypes = new ArrayList<>();
         notAttributeTypes = new ArrayList<>();
         auxObjectClasses = new ArrayList<>();
+        computeHashCode();
     }
 
 
@@ -182,10 +182,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            auxObjectClassOids.add( oid );
-        }
+        auxObjectClassOids.add( oid );
+        
+        computeHashCode();
     }
 
 
@@ -201,10 +200,12 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !auxObjectClassOids.contains( objectClass.getOid() ) )
+        if ( !auxObjectClassOids.contains( objectClass.getOid() ) )
         {
             auxObjectClasses.add( objectClass );
             auxObjectClassOids.add( objectClass.getOid() );
+            
+            computeHashCode();
         }
     }
 
@@ -219,10 +220,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.auxObjectClassOids = auxObjectClassOids;
-        }
+        this.auxObjectClassOids = auxObjectClassOids;
+        
+        computeHashCode();
     }
 
 
@@ -236,18 +236,17 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.auxObjectClasses = auxObjectClasses;
+        this.auxObjectClasses = auxObjectClasses;
 
-            // update the OIDS now
-            auxObjectClassOids.clear();
+        // update the OIDS now
+        auxObjectClassOids.clear();
 
-            for ( ObjectClass oc : auxObjectClasses )
-            {
-                auxObjectClassOids.add( oc.getOid() );
-            }
+        for ( ObjectClass oc : auxObjectClasses )
+        {
+            auxObjectClassOids.add( oc.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -281,10 +280,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            mayAttributeTypeOids.add( oid );
-        }
+        mayAttributeTypeOids.add( oid );
+        
+        computeHashCode();
     }
 
 
@@ -300,10 +298,12 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
+        if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
         {
             mayAttributeTypes.add( attributeType );
             mayAttributeTypeOids.add( attributeType.getOid() );
+            
+            computeHashCode();
         }
     }
 
@@ -318,10 +318,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mayAttributeTypeOids = mayAttributeTypeOids;
-        }
+        this.mayAttributeTypeOids = mayAttributeTypeOids;
+        
+        computeHashCode();
     }
 
 
@@ -337,18 +336,17 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mayAttributeTypes = mayAttributeTypes;
+        this.mayAttributeTypes = mayAttributeTypes;
 
-            // update the OIDS now
-            mayAttributeTypeOids.clear();
+        // update the OIDS now
+        mayAttributeTypeOids.clear();
 
-            for ( AttributeType may : mayAttributeTypes )
-            {
-                mayAttributeTypeOids.add( may.getOid() );
-            }
+        for ( AttributeType may : mayAttributeTypes )
+        {
+            mayAttributeTypeOids.add( may.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -382,10 +380,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            mustAttributeTypeOids.add( oid );
-        }
+        mustAttributeTypeOids.add( oid );
+        
+        computeHashCode();
     }
 
 
@@ -401,10 +398,12 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
+        if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
         {
             mustAttributeTypes.add( attributeType );
             mustAttributeTypeOids.add( attributeType.getOid() );
+            
+            computeHashCode();
         }
     }
 
@@ -419,10 +418,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mustAttributeTypeOids = mustAttributeTypeOids;
-        }
+        this.mustAttributeTypeOids = mustAttributeTypeOids;
+        
+        computeHashCode();
     }
 
 
@@ -438,18 +436,17 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mustAttributeTypes = mustAttributeTypes;
+        this.mustAttributeTypes = mustAttributeTypes;
 
-            // update the OIDS now
-            mustAttributeTypeOids.clear();
+        // update the OIDS now
+        mustAttributeTypeOids.clear();
 
-            for ( AttributeType may : mustAttributeTypes )
-            {
-                mustAttributeTypeOids.add( may.getOid() );
-            }
+        for ( AttributeType may : mustAttributeTypes )
+        {
+            mustAttributeTypeOids.add( may.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -483,10 +480,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            notAttributeTypeOids.add( oid );
-        }
+        notAttributeTypeOids.add( oid );
+        
+        computeHashCode();
     }
 
 
@@ -502,10 +498,12 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !notAttributeTypeOids.contains( attributeType.getOid() ) )
+        if ( !notAttributeTypeOids.contains( attributeType.getOid() ) )
         {
             notAttributeTypes.add( attributeType );
             notAttributeTypeOids.add( attributeType.getOid() );
+            
+            computeHashCode();
         }
     }
 
@@ -520,10 +518,9 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.notAttributeTypeOids = notAttributeTypeOids;
-        }
+        this.notAttributeTypeOids = notAttributeTypeOids;
+        
+        computeHashCode();
     }
 
 
@@ -539,18 +536,17 @@ public class DitContentRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.notAttributeTypes = notAttributeTypes;
+        this.notAttributeTypes = notAttributeTypes;
 
-            // update the OIDS now
-            notAttributeTypeOids.clear();
+        // update the OIDS now
+        notAttributeTypeOids.clear();
 
-            for ( AttributeType not : notAttributeTypes )
-            {
-                notAttributeTypeOids.add( not.getOid() );
-            }
+        for ( AttributeType not : notAttributeTypes )
+        {
+            notAttributeTypeOids.add( not.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -674,5 +670,6 @@ public class DitContentRule extends AbstractSchemaObject
         mustAttributeTypeOids.clear();
         notAttributeTypes.clear();
         notAttributeTypeOids.clear();
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitStructureRule.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitStructureRule.java
index 9d6c0a4..af536c2 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitStructureRule.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DitStructureRule.java
@@ -104,6 +104,7 @@ public class DitStructureRule extends AbstractSchemaObject
         this.ruleId = ruleId;
         form = null;
         superRules = new ArrayList<>();
+        computeHashCode();
     }
 
 
@@ -128,10 +129,8 @@ public class DitStructureRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.form = form;
-        }
+        this.form = form;
+        computeHashCode();
     }
 
 
@@ -156,10 +155,8 @@ public class DitStructureRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.ruleId = ruleId;
-        }
+        this.ruleId = ruleId;
+        computeHashCode();
     }
 
 
@@ -184,10 +181,8 @@ public class DitStructureRule extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.superRules = superRules;
-        }
+        this.superRules = superRules;
+        computeHashCode();
     }
 
 
@@ -204,6 +199,8 @@ public class DitStructureRule extends AbstractSchemaObject
         }
 
         superRules.add( superRule );
+        
+        computeHashCode();
     }
 
 
@@ -291,5 +288,7 @@ public class DitStructureRule extends AbstractSchemaObject
 
         // Clear the references
         superRules.clear();
+        
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LdapSyntax.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LdapSyntax.java
index a78da62..3058764 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LdapSyntax.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LdapSyntax.java
@@ -90,6 +90,7 @@ public class LdapSyntax extends AbstractSchemaObject
     public LdapSyntax( String oid )
     {
         super( SchemaObjectType.LDAP_SYNTAX, oid );
+        computeHashCode();
     }
 
 
@@ -104,6 +105,7 @@ public class LdapSyntax extends AbstractSchemaObject
         super( SchemaObjectType.LDAP_SYNTAX, oid );
         this.description = description;
         this.hasHumanReadableFlag = false;
+        computeHashCode();
     }
 
 
@@ -120,6 +122,7 @@ public class LdapSyntax extends AbstractSchemaObject
         this.description = description;
         this.isHumanReadable = isHumanReadable;
         this.hasHumanReadableFlag = true;
+        computeHashCode();
     }
 
 
@@ -175,11 +178,9 @@ public class LdapSyntax extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.isHumanReadable = humanReadable;
-            this.hasHumanReadableFlag = true;
-        }
+        this.isHumanReadable = humanReadable;
+        this.hasHumanReadableFlag = true;
+        computeHashCode();
     }
 
 
@@ -207,10 +208,8 @@ public class LdapSyntax extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.syntaxChecker = syntaxChecker;
-        }
+        this.syntaxChecker = syntaxChecker;
+        computeHashCode();
     }
 
 
@@ -227,6 +226,7 @@ public class LdapSyntax extends AbstractSchemaObject
         }
 
         this.syntaxChecker = newSyntaxChecker;
+        computeHashCode();
     }
 
 
@@ -316,5 +316,7 @@ public class LdapSyntax extends AbstractSchemaObject
 
         // Clear the references
         syntaxChecker = null;
+        
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LoadableSchemaObject.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LoadableSchemaObject.java
index cda01c0..06356a7 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LoadableSchemaObject.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/LoadableSchemaObject.java
@@ -54,6 +54,7 @@ public abstract class LoadableSchemaObject extends AbstractSchemaObject
 
         fqcn = "";
         bytecode = null;
+        computeHashCode();
     }
 
 
@@ -68,6 +69,7 @@ public abstract class LoadableSchemaObject extends AbstractSchemaObject
 
         fqcn = "";
         bytecode = null;
+        computeHashCode();
     }
 
 
@@ -93,10 +95,8 @@ public abstract class LoadableSchemaObject extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.bytecode = bytecode;
-        }
+        this.bytecode = bytecode;
+        computeHashCode();
     }
 
 
@@ -121,10 +121,8 @@ public abstract class LoadableSchemaObject extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.fqcn = fqcn;
-        }
+        this.fqcn = fqcn;
+        computeHashCode();
     }
 
 
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRule.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRule.java
index ea05286..f4a9709 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRule.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRule.java
@@ -97,6 +97,7 @@ public class MatchingRule extends AbstractSchemaObject
     public MatchingRule( String oid )
     {
         super( SchemaObjectType.MATCHING_RULE, oid );
+        computeHashCode();
     }
 
 
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRuleUse.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRuleUse.java
index dbec06d..03377d2 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRuleUse.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MatchingRuleUse.java
@@ -104,6 +104,7 @@ public class MatchingRuleUse extends AbstractSchemaObject
 
         applicableAttributeOids = new ArrayList<>();
         applicableAttributes = new ArrayList<>();
+        computeHashCode();
     }
 
 
@@ -137,10 +138,8 @@ public class MatchingRuleUse extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.applicableAttributeOids = applicableAttributeOids;
-        }
+        this.applicableAttributeOids = applicableAttributeOids;
+        computeHashCode();
     }
 
 
@@ -156,18 +155,17 @@ public class MatchingRuleUse extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.applicableAttributes = applicableAttributes;
+        this.applicableAttributes = applicableAttributes;
 
-            // update the OIDS now
-            applicableAttributeOids.clear();
+        // update the OIDS now
+        applicableAttributeOids.clear();
 
-            for ( AttributeType at : applicableAttributes )
-            {
-                applicableAttributeOids.add( at.getOid() );
-            }
+        for ( AttributeType at : applicableAttributes )
+        {
+            applicableAttributeOids.add( at.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -183,9 +181,10 @@ public class MatchingRuleUse extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !applicableAttributeOids.contains( oid ) )
+        if ( !applicableAttributeOids.contains( oid ) )
         {
             applicableAttributeOids.add( oid );
+            computeHashCode();
         }
     }
 
@@ -202,10 +201,11 @@ public class MatchingRuleUse extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !applicableAttributeOids.contains( attributeType.getOid() ) )
+        if ( !applicableAttributeOids.contains( attributeType.getOid() ) )
         {
             applicableAttributes.add( attributeType );
             applicableAttributeOids.add( attributeType.getOid() );
+            computeHashCode();
         }
     }
 
@@ -283,5 +283,6 @@ public class MatchingRuleUse extends AbstractSchemaObject
         // Clear the references
         applicableAttributes.clear();
         applicableAttributeOids.clear();
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableAttributeType.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableAttributeType.java
index 233ce1d..c150541 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableAttributeType.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableAttributeType.java
@@ -141,6 +141,8 @@ public class MutableAttributeType extends AttributeType
     public MutableAttributeType( String oid )
     {
         super( oid );
+        
+        computeHashCode();
     }
 
 
@@ -156,10 +158,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.isSingleValued = singleValued;
-        }
+        this.isSingleValued = singleValued;
+
+        computeHashCode();
     }
 
 
@@ -175,10 +176,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.canUserModify = userModifiable;
-        }
+        this.canUserModify = userModifiable;
+
+        computeHashCode();
     }
 
 
@@ -195,6 +195,8 @@ public class MutableAttributeType extends AttributeType
         }
 
         this.isCollective = collective;
+
+        computeHashCode();
     }
 
 
@@ -210,10 +212,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.isCollective = collective;
-        }
+        this.isCollective = collective;
+
+        computeHashCode();
     }
 
 
@@ -236,10 +237,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.usage = usage;
-        }
+        this.usage = usage;
+
+        computeHashCode();
     }
 
 
@@ -263,6 +263,8 @@ public class MutableAttributeType extends AttributeType
         }
 
         this.usage = newUsage;
+    
+        computeHashCode();
     }
 
 
@@ -279,10 +281,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.syntaxLength = length;
-        }
+        this.syntaxLength = length;
+
+        computeHashCode();
     }
 
 
@@ -298,10 +299,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.superiorOid = superiorOid;
-        }
+        this.superiorOid = superiorOid;
+
+        computeHashCode();
     }
 
 
@@ -317,11 +317,10 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.superior = superior;
-            this.superiorOid = superior.getOid();
-        }
+        this.superior = superior;
+        this.superiorOid = superior.getOid();
+
+        computeHashCode();
     }
 
 
@@ -337,10 +336,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.superiorOid = newSuperiorOid;
-        }
+        this.superiorOid = newSuperiorOid;
+
+        computeHashCode();
     }
 
 
@@ -358,6 +356,8 @@ public class MutableAttributeType extends AttributeType
 
         this.superior = newSuperior;
         this.superiorOid = newSuperior.getOid();
+
+        computeHashCode();
     }
 
 
@@ -373,10 +373,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.syntaxOid = syntaxOid;
-        }
+        this.syntaxOid = syntaxOid;
+
+        computeHashCode();
     }
 
 
@@ -392,11 +391,10 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.syntax = syntax;
-            this.syntaxOid = syntax.getOid();
-        }
+        this.syntax = syntax;
+        this.syntaxOid = syntax.getOid();
+
+        computeHashCode();
     }
 
 
@@ -414,6 +412,8 @@ public class MutableAttributeType extends AttributeType
 
         this.syntax = newSyntax;
         this.syntaxOid = newSyntax.getOid();
+
+        computeHashCode();
     }
 
 
@@ -429,10 +429,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.equalityOid = equalityOid;
-        }
+        this.equalityOid = equalityOid;
+
+        computeHashCode();
     }
 
 
@@ -448,11 +447,10 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.equality = equality;
-            this.equalityOid = equality.getOid();
-        }
+        this.equality = equality;
+        this.equalityOid = equality.getOid();
+
+        computeHashCode();
     }
 
 
@@ -470,6 +468,8 @@ public class MutableAttributeType extends AttributeType
 
         this.equality = newEquality;
         this.equalityOid = newEquality.getOid();
+
+        computeHashCode();
     }
 
 
@@ -485,10 +485,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.orderingOid = orderingOid;
-        }
+        this.orderingOid = orderingOid;
+
+        computeHashCode();
     }
 
 
@@ -504,11 +503,10 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.ordering = ordering;
-            this.orderingOid = ordering.getOid();
-        }
+        this.ordering = ordering;
+        this.orderingOid = ordering.getOid();
+
+        computeHashCode();
     }
 
 
@@ -526,6 +524,8 @@ public class MutableAttributeType extends AttributeType
 
         this.ordering = newOrdering;
         this.orderingOid = newOrdering.getOid();
+
+        computeHashCode();
     }
 
 
@@ -541,10 +541,9 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.substringOid = substrOid;
-        }
+        this.substringOid = substrOid;
+
+        computeHashCode();
     }
 
 
@@ -560,11 +559,10 @@ public class MutableAttributeType extends AttributeType
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.substring = substring;
-            this.substringOid = substring.getOid();
-        }
+        this.substring = substring;
+        this.substringOid = substring.getOid();
+
+        computeHashCode();
     }
 
 
@@ -582,6 +580,8 @@ public class MutableAttributeType extends AttributeType
 
         this.substring = newSubstring;
         this.substringOid = newSubstring.getOid();
+
+        computeHashCode();
     }
 
 
@@ -600,5 +600,7 @@ public class MutableAttributeType extends AttributeType
         substring = null;
         superior = null;
         syntax = null;
+        
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableMatchingRule.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableMatchingRule.java
index 9ebac1e..4224d40 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableMatchingRule.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableMatchingRule.java
@@ -86,6 +86,7 @@ public class MutableMatchingRule extends MatchingRule
     public MutableMatchingRule( String oid )
     {
         super( oid );
+        computeHashCode();
     }
 
 
@@ -101,10 +102,8 @@ public class MutableMatchingRule extends MatchingRule
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.ldapSyntaxOid = oid;
-        }
+        this.ldapSyntaxOid = oid;
+        computeHashCode();
     }
 
 
@@ -120,11 +119,9 @@ public class MutableMatchingRule extends MatchingRule
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.ldapSyntax = ldapSyntax;
-            this.ldapSyntaxOid = ldapSyntax.getOid();
-        }
+        this.ldapSyntax = ldapSyntax;
+        this.ldapSyntaxOid = ldapSyntax.getOid();
+        computeHashCode();
     }
 
 
@@ -142,6 +139,7 @@ public class MutableMatchingRule extends MatchingRule
 
         this.ldapSyntax = ldapSyntax;
         this.ldapSyntaxOid = ldapSyntax.getOid();
+        computeHashCode();
     }
 
 
@@ -158,10 +156,8 @@ public class MutableMatchingRule extends MatchingRule
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.ldapComparator = ( LdapComparator<? super Object> ) ldapComparator;
-        }
+        this.ldapComparator = ( LdapComparator<? super Object> ) ldapComparator;
+        computeHashCode();
     }
 
 
@@ -179,6 +175,7 @@ public class MutableMatchingRule extends MatchingRule
         }
 
         this.ldapComparator = ( LdapComparator<? super Object> ) ldapComparator;
+        computeHashCode();
     }
 
 
@@ -194,10 +191,8 @@ public class MutableMatchingRule extends MatchingRule
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.normalizer = normalizer;
-        }
+        this.normalizer = normalizer;
+        computeHashCode();
     }
 
 
@@ -214,6 +209,7 @@ public class MutableMatchingRule extends MatchingRule
         }
 
         this.normalizer = normalizer;
+        computeHashCode();
     }
 
 
@@ -230,5 +226,6 @@ public class MutableMatchingRule extends MatchingRule
         ldapComparator = null;
         ldapSyntax = null;
         normalizer = null;
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableObjectClass.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableObjectClass.java
index 93d8c02..1a1250d 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableObjectClass.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/MutableObjectClass.java
@@ -95,13 +95,12 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
+        for ( String oid : oids )
         {
-            for ( String oid : oids )
-            {
-                mayAttributeTypeOids.add( oid );
-            }
+            mayAttributeTypeOids.add( oid );
         }
+        
+        computeHashCode();
     }
 
 
@@ -117,17 +116,16 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
+        for ( AttributeType attributeType : attributeTypes )
         {
-            for ( AttributeType attributeType : attributeTypes )
+            if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
             {
-                if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
-                {
-                    mayAttributeTypes.add( attributeType );
-                    mayAttributeTypeOids.add( attributeType.getOid() );
-                }
+                mayAttributeTypes.add( attributeType );
+                mayAttributeTypeOids.add( attributeType.getOid() );
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -141,10 +139,8 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mayAttributeTypeOids = mayAttributeTypeOids;
-        }
+        this.mayAttributeTypeOids = mayAttributeTypeOids;
+        computeHashCode();
     }
 
 
@@ -160,18 +156,17 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mayAttributeTypes = mayAttributeTypes;
+        this.mayAttributeTypes = mayAttributeTypes;
 
-            // update the OIDS now
-            mayAttributeTypeOids.clear();
+        // update the OIDS now
+        mayAttributeTypeOids.clear();
 
-            for ( AttributeType may : mayAttributeTypes )
-            {
-                mayAttributeTypeOids.add( may.getOid() );
-            }
+        for ( AttributeType may : mayAttributeTypes )
+        {
+            mayAttributeTypeOids.add( may.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -182,6 +177,11 @@ public class MutableObjectClass extends ObjectClass
      */
     public void updateMayAttributeTypes( List<AttributeType> mayAttributeTypes )
     {
+        if ( locked )
+        {
+            throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
+        }
+
         this.mayAttributeTypes.clear();
         this.mayAttributeTypes.addAll( mayAttributeTypes );
 
@@ -207,13 +207,12 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
+        for ( String oid : oids )
         {
-            for ( String oid : oids )
-            {
-                mustAttributeTypeOids.add( oid );
-            }
+            mustAttributeTypeOids.add( oid );
         }
+        
+        computeHashCode();
     }
 
 
@@ -229,17 +228,16 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
+        for ( AttributeType attributeType : attributeTypes )
         {
-            for ( AttributeType attributeType : attributeTypes )
+            if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
             {
-                if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
-                {
-                    mustAttributeTypes.add( attributeType );
-                    mustAttributeTypeOids.add( attributeType.getOid() );
-                }
+                mustAttributeTypes.add( attributeType );
+                mustAttributeTypeOids.add( attributeType.getOid() );
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -253,10 +251,8 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mustAttributeTypeOids = mustAttributeTypeOids;
-        }
+        this.mustAttributeTypeOids = mustAttributeTypeOids;
+        computeHashCode();
     }
 
 
@@ -272,18 +268,17 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mustAttributeTypes = mustAttributeTypes;
+        this.mustAttributeTypes = mustAttributeTypes;
 
-            // update the OIDS now
-            mustAttributeTypeOids.clear();
+        // update the OIDS now
+        mustAttributeTypeOids.clear();
 
-            for ( AttributeType may : mustAttributeTypes )
-            {
-                mustAttributeTypeOids.add( may.getOid() );
-            }
+        for ( AttributeType may : mustAttributeTypes )
+        {
+            mustAttributeTypeOids.add( may.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -294,6 +289,11 @@ public class MutableObjectClass extends ObjectClass
      */
     public void updateMustAttributeTypes( List<AttributeType> mustAttributeTypes )
     {
+        if ( locked )
+        {
+            throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
+        }
+
         this.mustAttributeTypes.clear();
         this.mustAttributeTypes.addAll( mustAttributeTypes );
 
@@ -319,16 +319,15 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
+        for ( String oid : oids )
         {
-            for ( String oid : oids )
+            if ( !superiorOids.contains( oid ) )
             {
-                if ( !superiorOids.contains( oid ) )
-                {
-                    superiorOids.add( oid );
-                }
+                superiorOids.add( oid );
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -344,17 +343,16 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
+        for ( MutableObjectClass objectClass : objectClasses )
         {
-            for ( MutableObjectClass objectClass : objectClasses )
+            if ( !superiorOids.contains( objectClass.getOid() ) )
             {
-                if ( !superiorOids.contains( objectClass.getOid() ) )
-                {
-                    superiorOids.add( objectClass.getOid() );
-                    superiors.add( objectClass );
-                }
+                superiorOids.add( objectClass.getOid() );
+                superiors.add( objectClass );
             }
         }
+        
+        computeHashCode();
     }
 
 
@@ -370,18 +368,17 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.superiors = superiors;
+        this.superiors = superiors;
 
-            // update the OIDS now
-            superiorOids.clear();
+        // update the OIDS now
+        superiorOids.clear();
 
-            for ( ObjectClass oc : superiors )
-            {
-                superiorOids.add( oc.getOid() );
-            }
+        for ( ObjectClass oc : superiors )
+        {
+            superiorOids.add( oc.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -392,6 +389,11 @@ public class MutableObjectClass extends ObjectClass
      */
     public void updateSuperiors( List<ObjectClass> superiors )
     {
+        if ( locked )
+        {
+            throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
+        }
+
         this.superiors.clear();
         this.superiors.addAll( superiors );
 
@@ -417,10 +419,8 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.superiorOids = superiorOids;
-        }
+        this.superiorOids = superiorOids;
+        computeHashCode();
     }
 
 
@@ -436,10 +436,8 @@ public class MutableObjectClass extends ObjectClass
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.objectClassType = objectClassType;
-        }
+        this.objectClassType = objectClassType;
+        computeHashCode();
     }
 
 
@@ -459,5 +457,6 @@ public class MutableObjectClass extends ObjectClass
         mustAttributeTypeOids.clear();
         superiors.clear();
         superiorOids.clear();
+        computeHashCode();
     }
 }
\ No newline at end of file
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/NameForm.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/NameForm.java
index 77a2758..cf5432a 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/NameForm.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/NameForm.java
@@ -128,6 +128,7 @@ public class NameForm extends AbstractSchemaObject
 
         mustAttributeTypes = new ArrayList<>();
         mayAttributeTypes = new ArrayList<>();
+        computeHashCode();
     }
 
 
@@ -167,10 +168,8 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.structuralObjectClassOid = structuralObjectClassOid;
-        }
+        this.structuralObjectClassOid = structuralObjectClassOid;
+        computeHashCode();
     }
 
 
@@ -186,11 +185,9 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.structuralObjectClass = structuralObjectClass;
-            this.structuralObjectClassOid = structuralObjectClass.getOid();
-        }
+        this.structuralObjectClass = structuralObjectClass;
+        this.structuralObjectClassOid = structuralObjectClass.getOid();
+        computeHashCode();
     }
 
 
@@ -232,10 +229,8 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mustAttributeTypeOids = mustAttributeTypeOids;
-        }
+        this.mustAttributeTypeOids = mustAttributeTypeOids;
+        computeHashCode();
     }
 
 
@@ -251,18 +246,17 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mustAttributeTypes = mustAttributeTypes;
+        this.mustAttributeTypes = mustAttributeTypes;
 
-            // update the OIDS now
-            mustAttributeTypeOids.clear();
+        // update the OIDS now
+        mustAttributeTypeOids.clear();
 
-            for ( AttributeType may : mustAttributeTypes )
-            {
-                mustAttributeTypeOids.add( may.getOid() );
-            }
+        for ( AttributeType may : mustAttributeTypes )
+        {
+            mustAttributeTypeOids.add( may.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -278,10 +272,8 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            mustAttributeTypeOids.add( oid );
-        }
+        mustAttributeTypeOids.add( oid );
+        computeHashCode();
     }
 
 
@@ -297,10 +289,11 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
+        if ( !mustAttributeTypeOids.contains( attributeType.getOid() ) )
         {
             mustAttributeTypes.add( attributeType );
             mustAttributeTypeOids.add( attributeType.getOid() );
+            computeHashCode();
         }
     }
 
@@ -343,10 +336,8 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mayAttributeTypeOids = mayAttributeTypeOids;
-        }
+        this.mayAttributeTypeOids = mayAttributeTypeOids;
+        computeHashCode();
     }
 
 
@@ -362,18 +353,17 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            this.mayAttributeTypes = mayAttributeTypes;
+        this.mayAttributeTypes = mayAttributeTypes;
 
-            // update the OIDS now
-            mayAttributeTypeOids.clear();
+        // update the OIDS now
+        mayAttributeTypeOids.clear();
 
-            for ( AttributeType may : mayAttributeTypes )
-            {
-                mayAttributeTypeOids.add( may.getOid() );
-            }
+        for ( AttributeType may : mayAttributeTypes )
+        {
+            mayAttributeTypeOids.add( may.getOid() );
         }
+        
+        computeHashCode();
     }
 
 
@@ -389,10 +379,8 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly )
-        {
-            mayAttributeTypeOids.add( oid );
-        }
+        mayAttributeTypeOids.add( oid );
+        computeHashCode();
     }
 
 
@@ -408,10 +396,11 @@ public class NameForm extends AbstractSchemaObject
             throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
         }
 
-        if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
+        if ( !mayAttributeTypeOids.contains( attributeType.getOid() ) )
         {
             mayAttributeTypes.add( attributeType );
             mayAttributeTypeOids.add( attributeType.getOid() );
+            computeHashCode();
         }
     }
 
@@ -508,5 +497,6 @@ public class NameForm extends AbstractSchemaObject
         mustAttributeTypes.clear();
         mustAttributeTypeOids.clear();
         structuralObjectClass = null;
+        computeHashCode();
     }
 }
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java
index d24fed6..e79e9bc 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java
@@ -109,6 +109,7 @@ public class ObjectClass extends AbstractSchemaObject
         mustAttributeTypes = new ArrayList<>();
         superiors = new ArrayList<>();
         objectClassType = ObjectClassTypeEnum.STRUCTURAL;
+        computeHashCode();
     }
 
 
diff --git a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObject.java b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObject.java
index 0b225a9..b6f2574 100644
--- a/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObject.java
+++ b/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObject.java
@@ -184,22 +184,6 @@ public interface SchemaObject
 
 
     /**
-     * Tells if this SchemaObject is ReadOnly.
-     * 
-     * @return true if the SchemaObject is not modifiable
-     */
-    boolean isReadOnly();
-
-
-    /**
-     * Sets the SchemaObject readOnly flag
-     * 
-     * @param isReadOnly The current SchemaObject ReadOnly status
-     */
-    void setReadOnly( boolean isReadOnly );
-
-
-    /**
      * Gets whether or not this SchemaObject has been inactivated. All
      * SchemaObjects except Syntaxes allow for this parameter within their
      * definition. For Syntaxes this property should always return false in
diff --git a/ldap/schema/data/src/main/java/org/apache/directory/api/ldap/schema/loader/SchemaEntityFactory.java b/ldap/schema/data/src/main/java/org/apache/directory/api/ldap/schema/loader/SchemaEntityFactory.java
index 792c23f..fe4c9f3 100644
--- a/ldap/schema/data/src/main/java/org/apache/directory/api/ldap/schema/loader/SchemaEntityFactory.java
+++ b/ldap/schema/data/src/main/java/org/apache/directory/api/ldap/schema/loader/SchemaEntityFactory.java
@@ -1504,7 +1504,6 @@ public class SchemaEntityFactory implements EntityFactory
      *  - schemaName
      *  - specification (if any)
      *  - extensions
-     *  - isReadOnly
      *  - isEnabled
      *  
      *  @param schemaObject The SchemaObject to set
@@ -1526,11 +1525,6 @@ public class SchemaEntityFactory implements EntityFactory
         // Disable field, we will inherit from the schema enable field
         schemaObject.setEnabled( schema.isEnabled() );
 
-        // The isReadOnly field. We don't have this data in the description,
-        // so set it to false
-        // TODO : should it be a X-READONLY extension ?
-        schemaObject.setReadOnly( false );
-
         // The specification field
         schemaObject.setSpecification( description.getSpecification() );