Assistance needed with serialization, inheritance and scriptableobject

So I’ve hit that roadblock of “I’m trying to serialize child classes but everything is being serialized as the parent class”. I expected this, but despite the base class inheriting from ScriptableObject, I can’t seem to store my instances in a .asset file, as they’re showing up with a Type Mismatch error.

Here’s an example:
I have a generic ScriptableObjectDatabase class, which should be capable of storing whatever I pass it:

public class ScriptableObjectDatabase<T> : ScriptableObject where T : class
{
	[SerializeField] protected List<T> database = new List<T>();

    public static T GetDatabase<T>(string dbPath, string dbName) where T : ScriptableObject
    {
        var dbFullPath = @"Assets/" + dbPath + "/" + dbName;

        var db = AssetDatabase.LoadAssetAtPath(dbFullPath, typeof(T)) as T;

        if (db != null) return db;

        if (!AssetDatabase.IsValidFolder("Assets/" + dbPath))
            AssetDatabase.CreateFolder("Assets", dbPath);

        db = CreateInstance<T>();
        AssetDatabase.CreateAsset(db, dbFullPath);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        return db;
    }
}

Then different types of databases exist with different functionality, the one I’m working on now being the ItemDatabase which does very little. So I have an Item class, which is the base for other classes, such as Equipment etc.

public class Item : ScriptableObject
{
    //fields etc
}

public class Equipment : Item
{
    //equipment specific fields
}

I then have an item editor window, which is responsible for managing the items in a .asset file.

public class ItemEditor : EditorWindow
{
	private ItemDatabase itemDatabase;
	
	private void OnEnable()
	{
		if (itemDatabase == null)
			itemDatabase = ItemDatabase.GetDatabase<ItemDatabase>(DATABASE_PATH, ITEM_DATABASE_NAME);
	}
	
	private void OnGUI()
	{
		if (GUILayout.Button("Add"))
		{
			ItemDatabase.Add(CreateInstance<Item>());
		}
	}
}

Then finally when I look at the database via the inspector, I see the following:
87538-testscript.png
I’m assuming that the information inside the database is no longer saving as SetDirty(itemDatabase) isn’t enough to trigger saving the scriptable object? I can edit things on the fly but writing them to disk isn’t working out right now.

Any guidance on what I’m doing wrong would be greatly appreciated.

Is there a reason your generic type constraint on ScriptableObjectDatabase is simply class? It seems to me like it should be ScriptableObject. I wonder if that would make the difference.

Also, I’d suggest for readability that you rewrite the signature for GetItemDatabase as something like public static TDatabase GetItemDatabase<TDatabase> (string dbPath, string dbName) where TDatabase : ScriptableObjectDatabase<T>