diff --git a/app/Classes/LDAP/Attribute.php b/app/Classes/LDAP/Attribute.php
index f1002662..1fcc33ee 100644
--- a/app/Classes/LDAP/Attribute.php
+++ b/app/Classes/LDAP/Attribute.php
@@ -20,9 +20,6 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 	// Is this attribute an internal attribute
 	protected(set) bool $is_internal = FALSE;
 
-	// Is this attribute the RDN?
-	public bool $is_rdn = FALSE;
-
 	// MIN/MAX number of values
 	protected(set) int $min_values_count = 0;
 	protected(set) int $max_values_count = 0;
@@ -40,7 +37,7 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 	protected(set) Collection $values_old;
 	// Current Values
 	public Collection $values;
-	// The other object classes of the entry that include this attribute
+	// The objectclasses of the entry that has this attribute
 	protected(set) Collection $oc;
 
 	/*
@@ -100,7 +97,7 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 	 * @param string $dn DN this attribute is used in
 	 * @param string $name Name of the attribute
 	 * @param array $values Current Values
-	 * @param array $oc ObjectClasses that the DN has, that includes this attribute
+	 * @param array $oc The objectclasses that the DN of this attribute has
 	 */
 	public function __construct(string $dn,string $name,array $values,array $oc=[])
 	{
@@ -143,6 +140,10 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 			'hints' => $this->hints(),
 			// Can this attribute be edited
 			'is_editable' => $this->schema ? $this->schema->{$key} : NULL,
+			// Objectclasses that required this attribute for an LDAP entry
+			'required' => $this->required(),
+			// Is this attribute an RDN attribute
+			'is_rdn' => $this->isRDN(),
 			// We prefer the name as per the schema if it exists
 			'name' => $this->schema ? $this->schema->{$key} : $this->{$key},
 			// Attribute name in lower case
@@ -232,11 +233,8 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 		// If this attribute name is an alias for the schema attribute name
 		// @todo
 
-		// objectClasses requiring this attribute
-		// @todo limit this to this DNs objectclasses
-		// eg: $result->put('required','Required by objectClasses: a,b');
-		if ($this->required_by->count())
-			$result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required_by->join(',')));
+		if ($this->required()->count())
+			$result->put(__('required'),sprintf('%s: %s',__('Required Attribute by ObjectClass(es)'),$this->required()->join(', ')));
 
 		// This attribute has language tags
 		if ($this->lang_tags->count())
@@ -256,6 +254,22 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 			|| ($this->values->diff($this->values_old)->count() !== 0);
 	}
 
+	/**
+	 * Work out if this attribute is an RDN attribute
+	 *
+	 * @return bool
+	 */
+	public function isRDN(): bool
+	{
+		// If we dont have an DN, then we cant know
+		if (! $this->dn)
+			return FALSE;
+
+		$rdns = collect(explode('+',substr($this->dn,0,strpos($this->dn,','))));
+
+		return $rdns->filter(fn($item) => str_starts_with($item,$this->name.'='))->count() > 0;
+	}
+
 	/**
 	 * Display the attribute value
 	 *
@@ -287,6 +301,19 @@ class Attribute implements \Countable, \ArrayAccess, \Iterator
 		return Arr::get($this->values,$key);
 	}
 
+	/**
+	 * Work out if this attribute is required by an objectClass the entry has
+	 *
+	 * @return Collection
+	 */
+	public function required(): Collection
+	{
+		// If we dont have any objectclasses then we cant know if it is required
+		return $this->oc->count()
+			? $this->oc->intersect($this->schema->required_by_object_classes->keys())->sort()
+			: collect();
+	}
+
 	/**
 	 * If this attribute has RFC3866 Language Tags, this will enable those values to be captured
 	 *
diff --git a/app/Classes/LDAP/Attribute/ObjectClass.php b/app/Classes/LDAP/Attribute/ObjectClass.php
index 2667b0be..959429b3 100644
--- a/app/Classes/LDAP/Attribute/ObjectClass.php
+++ b/app/Classes/LDAP/Attribute/ObjectClass.php
@@ -21,15 +21,15 @@ final class ObjectClass extends Attribute
 	 * @param string $dn DN this attribute is used in
 	 * @param string $name Name of the attribute
 	 * @param array $values Current Values
-	 * @param array $oc ObjectClasses that the DN has, that includes this attribute
+	 * @param array $oc The objectclasses that the DN of this attribute has
 	 */
 	public function __construct(string $dn,string $name,array $values,array $oc=[])
 	{
-		parent::__construct($dn,$name,$values,$oc);
+		parent::__construct($dn,$name,$values,['top']);
 
 		$this->oc_schema = config('server')
 			->schema('objectclasses')
-			->filter(fn($item)=>$this->values->contains($item->name));
+			->filter(fn($item)=>$this->values->merge($this->values_old)->unique()->contains($item->name));
 	}
 
 	public function __get(string $key): mixed
diff --git a/app/Classes/LDAP/Schema/AttributeType.php b/app/Classes/LDAP/Schema/AttributeType.php
index 49d8f841..a33631d2 100644
--- a/app/Classes/LDAP/Schema/AttributeType.php
+++ b/app/Classes/LDAP/Schema/AttributeType.php
@@ -320,11 +320,12 @@ final class AttributeType extends Base {
 	 * that is the list of objectClasses which must have this attribute.
 	 *
 	 * @param string $name The name of the objectClass to add.
+	 * @param bool $structural
 	 */
-	public function addRequiredByObjectClass(string $name): void
+	public function addRequiredByObjectClass(string $name,bool $structural): void
 	{
-		if (! $this->required_by_object_classes->contains($name))
-			$this->required_by_object_classes->push($name);
+		if (! $this->required_by_object_classes->has($name))
+			$this->required_by_object_classes->put($name,$structural);
 	}
 
 	/**
@@ -332,6 +333,7 @@ final class AttributeType extends Base {
 	 * that is the list of objectClasses which provide this attribute.
 	 *
 	 * @param string $name The name of the objectClass to add.
+	 * @param bool $structural
 	 */
 	public function addUsedInObjectClass(string $name,bool $structural): void
 	{
@@ -544,7 +546,7 @@ final class AttributeType extends Base {
 	 */
 	public function validation(array $array): ?array
 	{
-		// For each item in array, we need to get the OC heirachy
+		// For each item in array, we need to get the OC hierarchy
 		$heirachy = collect($array)
 			->filter()
 			->map(fn($item)=>config('server')
diff --git a/app/Classes/LDAP/Server.php b/app/Classes/LDAP/Server.php
index cf2e3695..19bd9346 100644
--- a/app/Classes/LDAP/Server.php
+++ b/app/Classes/LDAP/Server.php
@@ -428,7 +428,7 @@ final class Server
 						// Add Required By.
 						foreach ($must_attrs as $attr_name)
 							if ($this->attributetypes->has(strtolower($attr_name)))
-								$this->attributetypes[strtolower($attr_name)]->addRequiredByObjectClass($object_class->name);
+								$this->attributetypes[strtolower($attr_name)]->addRequiredByObjectClass($object_class->name,$object_class->isStructural());
 
 						// Force May
 						foreach ($object_class->getForceMayAttrs() as $attr_name)
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index c11cc4b5..c47bce69 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -92,10 +92,10 @@ class HomeController extends Controller
 
 		return $request->noheader
 			? view(sprintf('components.attribute.widget.%s',$id))
-				->with('o',Factory::create($dn,$id,[],$request->oc ?: []))
+				->with('o',Factory::create($dn,$id,[],$request->objectclasses))
 				->with('value',$request->value)
 				->with('loop',$xx)
-			: (new AttributeType(Factory::create($dn,$id,[],$request->oc ?: []),TRUE,collect($request->oc ?: [])))->render();
+			: new AttributeType(Factory::create($dn,$id,[],$request->objectclasses),TRUE)->render();
 	}
 
 	public function entry_create(EntryAddRequest $request): \Illuminate\Http\RedirectResponse
diff --git a/app/Ldap/Entry.php b/app/Ldap/Entry.php
index 937efcd5..0fc56313 100644
--- a/app/Ldap/Entry.php
+++ b/app/Ldap/Entry.php
@@ -16,7 +16,9 @@ use App\Exceptions\InvalidUsage;
 
 class Entry extends Model
 {
+	// Our Attribute objects
 	private Collection $objects;
+	/* @deprecated */
 	private bool $noObjectAttributes = FALSE;
 	// For new entries, this is the container that this entry will be stored in
 	private string $rdnbase;
@@ -176,6 +178,7 @@ class Entry extends Model
 	private function getAttributesAsObjects(): Collection
 	{
 		$result = collect();
+		$entry_oc = Arr::get($this->attributes,'objectclass',[]);
 
 		foreach ($this->attributes as $attribute => $values) {
 			// If the attribute name has tags
@@ -184,17 +187,22 @@ class Entry extends Model
 				$attribute = $matches[1];
 
 				// If the attribute doesnt exist we'll create it
-				$o = Arr::get($result,$attribute,Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),Arr::get($this->original,'objectclass',[])));
+				$o = Arr::get(
+					$result,
+					$attribute,
+					Factory::create(
+						$this->dn,
+						$attribute,
+						Arr::get($this->original,$attribute,[]),
+						$entry_oc,
+					));
 				$o->setLangTag($matches[3],$values);
 
 			} else {
-				$o = Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),Arr::get($this->original,'objectclass',[]));
+				$o = Factory::create($this->dn,$attribute,Arr::get($this->original,$attribute,[]),$entry_oc);
 			}
 
 			if (! $result->has($attribute)) {
-				// Set the rdn flag
-				$o->is_rdn = preg_match('/^'.$attribute.'=/i',$this->dn);
-
 				// Store our new values to know if this attribute has changed
 				$o->values = collect($values);
 
@@ -306,7 +314,7 @@ class Entry extends Model
 	private function getRDNObject(): Attribute\RDN
 	{
 		$o = new Attribute\RDN('','dn',['']);
-		// @todo for an existing object, return the base.
+		// @todo for an existing object, rdnbase would be null, so dynamically get it from the DN.
 		$o->setBase($this->rdnbase);
 		$o->setAttributes($this->getAvailableAttributes()->filter(fn($item)=>$item->required));
 
@@ -430,6 +438,7 @@ class Entry extends Model
 	 * Dont convert our $this->attributes to $this->objects when creating a new Entry::class
 	 *
 	 * @return $this
+	 * @deprecated
 	 */
 	public function noObjectAttributes(): static
 	{
diff --git a/app/View/Components/AttributeType.php b/app/View/Components/AttributeType.php
index 36477a73..6c3dcb57 100644
--- a/app/View/Components/AttributeType.php
+++ b/app/View/Components/AttributeType.php
@@ -11,17 +11,15 @@ use App\Classes\LDAP\Attribute as LDAPAttribute;
 
 class AttributeType extends Component
 {
-	public Collection $oc;
-	public LDAPAttribute $o;
-	public bool $new;
+	private LDAPAttribute $o;
+	private bool $new;
 
 	/**
 	 * Create a new component instance.
 	 */
-	public function __construct(LDAPAttribute $o,bool $new=FALSE,?Collection $oc=NULL)
+	public function __construct(LDAPAttribute $o,bool $new=FALSE)
 	{
 		$this->o = $o;
-		$this->oc = $oc;
 		$this->new = $new;
 	}
 
@@ -32,7 +30,6 @@ class AttributeType extends Component
 	{
 		return view('components.attribute-type')
 			->with('o',$this->o)
-			->with('oc',$this->oc)
 			->with('new',$this->new);
 	}
 }
\ No newline at end of file
diff --git a/resources/views/fragment/schema/attributetypes.blade.php b/resources/views/fragment/schema/attributetypes.blade.php
index ba25b200..e5c3d7be 100644
--- a/resources/views/fragment/schema/attributetypes.blade.php
+++ b/resources/views/fragment/schema/attributetypes.blade.php
@@ -106,6 +106,24 @@
 							@endif
 						</td>
 					</tr>
+					<tr>
+						<td>@lang('Required by ObjectClasses')</td>
+						<td>
+							@if ($o->required_by_object_classes->count())
+								@foreach ($o->required_by_object_classes as $class => $structural)
+									@if($structural)
+										<strong>
+									@endif
+									<a class="objectclass" id="{{ strtolower($class) }}" href="#{{ strtolower($class) }}">{{ $class }}</a>
+									@if($structural)
+										</strong>
+									@endif
+								@endforeach
+							@else
+								@lang('(none)')
+							@endif
+						</td>
+					</tr>
 					<tr>
 						<td>@lang('Force as MAY by config')</td><td><strong>@lang($o->forced_as_may ? 'Yes' : 'No')</strong></td>
 					</tr>