Skip to content

Fix nested JSON owned entities causing ArgumentNullException in EF Core 10#347

Merged
roji merged 3 commits intoefcore:mainfrom
brendonparker:bugfix/346
Jan 22, 2026
Merged

Fix nested JSON owned entities causing ArgumentNullException in EF Core 10#347
roji merged 3 commits intoefcore:mainfrom
brendonparker:bugfix/346

Conversation

@brendonparker
Copy link
Contributor

@brendonparker brendonparker commented Jan 22, 2026

Problem

When using naming conventions with JSON-mapped owned entities that have nested owned collections, an ArgumentNullException is thrown during query compilation:

System.ArgumentNullException: Value cannot be null. (Parameter 'key')
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor
      .ShaperProcessingExpressionVisitor.CreateJsonShapers(...)

This occurs when there are relations/children off of a entity marked with ToJson()

For example:

entity.OwnsOne(x => x.Details, details =>
{
    details.ToJson();
    details.OwnsMany(x => x.SubDetails); // This is currently problematic
});

Root Cause

The ProcessJsonOwnedEntity method was passing the parent's containerColumnName to all nested entities and calling SetContainerColumnName() on them. Nested JSON entities shouldn't have their own container column - they're part of the parent's JSON structure, not separate database columns.

When nested entities are off of an entity that has ToJson() called, they weren't being recognized as part of the JSON structure and were incorrectly processed.

Fix

  1. Detect when an owned entity is nested within an already JSON-mapped parent via foreignKey.PrincipalEntityType.IsMappedToJson()

  2. Handle nested JSON entities by clearing relational annotations and returning early - they don't need container column names

  3. Only rewrite the container column name on the root JSON entity

Fixes #346

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes an ArgumentNullException that occurs in EF Core 10 when using naming conventions with JSON-mapped owned entities that have nested owned collections. The issue was caused by incorrectly passing the parent's container column name to nested entities within a JSON structure.

Changes:

  • Added logic to detect when an owned entity is nested within a JSON-mapped parent entity
  • Modified handling to clear relational annotations for nested JSON entities without setting container column names
  • Refactored ProcessJsonOwnedEntity to remove the containerColumnName parameter, ensuring it's only set on root JSON entities
Comments suppressed due to low confidence (1)

EFCore.NamingConventions/Internal/NameRewritingConvention.cs:210

  • There is code duplication between lines 180-186 (nested JSON entity handling) and lines 202-210 (ProcessJsonOwnedEntity). The logic for clearing relational annotations (TableName, Schema, and ColumnName) is repeated. Consider extracting this into a helper method to improve maintainability.
                    ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName);
                    ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.Schema);

                    foreach (var property in ownedEntityType.GetProperties())
                    {
                        property.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
                    }

                    context.StopProcessing();
                    return;
                }

                if (ownedEntityType.GetContainerColumnName() is { } containerColumnName)
                {
                    // Rewrite container column name only on the root JSON entity.
                    ownedEntityType.SetContainerColumnName(_namingNameRewriter.RewriteName(containerColumnName));
                }

                ProcessJsonOwnedEntity(ownedEntityType);

                void ProcessJsonOwnedEntity(IConventionEntityType entityType)
                {
                    entityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName);
                    entityType.Builder.HasNoAnnotation(RelationalAnnotationNames.Schema);

                    // TODO: Note that we do not rewrite names of JSON properties (which aren't relational columns).
                    // TODO: We could introduce an option for doing so, though that's probably not usually what people want when doing JSON
                    foreach (var property in entityType.GetProperties())
                    {
                        property.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
                    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@roji roji merged commit 1df1c5f into efcore:main Jan 22, 2026
1 check passed
@roji
Copy link
Member

roji commented Jan 22, 2026

Thanks @brendonparker! I did a bit of cleanup and added test coverage, will release 10.0.1 with the fix shortly.

This was referenced Jan 22, 2026
This was referenced Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ArgumentNullException in CreateJsonShapers when using EFCore.NamingConventions 10.0.0 with JSON-owned entities

3 participants