Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not store mapping field in Configuration #3398

Merged
merged 16 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions src/NHibernate.Test/DialectTest/MsSql2008DialectFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,7 @@ public void ScaleTypes()
Assert.That(dialect.GetTypeName(SqlTypeFactory.GetTime(max + 1)), Is.EqualTo("time").IgnoreCase, "Over max time");
}

private static readonly FieldInfo _mappingField =
typeof(Configuration).GetField("mapping", BindingFlags.Instance | BindingFlags.NonPublic);

private static IMapping GetMapping(Configuration cfg)
{
Assert.That(_mappingField, Is.Not.Null, "Unable to find field mapping");
var mapping = _mappingField.GetValue(cfg) as IMapping;
Assert.That(mapping, Is.Not.Null, "Unable to find mapping object");
return mapping;
}
private static IMapping GetMapping(Configuration cfg) => (IMapping) cfg.BuildSessionFactory();
Copy link
Member Author

Choose a reason for hiding this comment

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

The true equivalent for the original code in the new way would be GetMapping(Configuration cfg) => cfg.BuildMapping(), but Dialect would throw an InvalidOperationException. However, in this case it does not matter and we can use fully resolved session factory instead.

Copy link
Member

Choose a reason for hiding this comment

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

Now new public "BuildMapping" can be used.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking about it and don't like it. cfg.BuildMapping just should not exist as it provides an incomplete version of mapping, that can create a lot of problems.

Copy link
Member

@bahusoid bahusoid Aug 15, 2023

Choose a reason for hiding this comment

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

nit: I don't understand your concern. In my understanding IMapping was specifically designed to be safely used in "uncompiled" state. See interface description:

/// Defines operations common to "compiled" mappings (ie. <c>SessionFactory</c>) and
/// "uncompiled" mappings (ie <c>Configuration</c> that are used by implementors of <c>IType</c>

So as long you use interface methods and don't do some funny castings you should be safe.

You agreed to keep method public - so it would be good to have it in tests too.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think the IMapping was designed. It was probably appeared incidentally from some other bad design decision. Problem with the interface that it is not clear when it is safe to use compiled or raw mappings. For example, SingleTableEntityPersister accepts both IMapping and ISessionFactoryImplementor. Can it use only ISessionFactoryImplementor?

public SingleTableEntityPersister(PersistentClass persistentClass, ICacheConcurrencyStrategy cache,
ISessionFactoryImplementor factory, IMapping mapping)
: base(persistentClass, cache, factory)

This is really not clear.

Also, Hibernate has removed this interface and redesigned the mapping compilation.


private static void AssertSqlType(IType type, SqlType sqlType, IMapping mapping)
{
Expand Down
102 changes: 41 additions & 61 deletions src/NHibernate/Cfg/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ public Configuration(SerializationInfo info, StreamingContext context)
FilterDefinitions = GetSerialedObject<IDictionary<string, FilterDefinition>>(info, "filterDefinitions");
Imports = GetSerialedObject<IDictionary<string, string>>(info, "imports");
interceptor = GetSerialedObject<IInterceptor>(info, "interceptor");
mapping = GetSerialedObject<IMapping>(info, "mapping");
NamedQueries = GetSerialedObject<IDictionary<string, NamedQueryDefinition>>(info, "namedQueries");
NamedSQLQueries = GetSerialedObject<IDictionary<string, NamedSQLQueryDefinition>>(info, "namedSqlQueries");
namingStrategy = GetSerialedObject<INamingStrategy>(info, "namingStrategy");
Expand All @@ -124,7 +123,6 @@ public void GetObjectData(SerializationInfo info, StreamingContext context)
{
ConfigureProxyFactoryFactory();
SecondPassCompile();
Validate();

info.AddValue("entityNotFoundDelegate", EntityNotFoundDelegate);

Expand All @@ -139,7 +137,6 @@ public void GetObjectData(SerializationInfo info, StreamingContext context)
info.AddValue("filterDefinitions", FilterDefinitions);
info.AddValue("imports", Imports);
info.AddValue("interceptor", interceptor);
info.AddValue("mapping", mapping);
info.AddValue("namedQueries", NamedQueries);
info.AddValue("namedSqlQueries", NamedSQLQueries);
info.AddValue("namingStrategy", namingStrategy);
Expand Down Expand Up @@ -246,10 +243,6 @@ private class StaticDialectMappingWrapper : IMapping
{
private readonly IMapping _mapping;

public StaticDialectMappingWrapper(IMapping mapping): this(mapping, mapping.Dialect)
{
}

public StaticDialectMappingWrapper(IMapping mapping, Dialect.Dialect dialect)
{
_mapping = mapping;
Expand Down Expand Up @@ -279,23 +272,25 @@ public bool HasNonIdentifierPropertyNamedId(string className)
public Dialect.Dialect Dialect { get; }
}

private IMapping mapping;

protected Configuration(SettingsFactory settingsFactory)
{
InitBlock();
this.settingsFactory = settingsFactory;
Reset();
}

private void InitBlock()
// Since v5.5
[Obsolete("Use BuildSessionFactory to obtain a new ISessionFactory instance instead.")]
bahusoid marked this conversation as resolved.
Show resolved Hide resolved
public virtual IMapping BuildMapping()
{
mapping = BuildMapping();
return new Mapping(this);
}

public virtual IMapping BuildMapping()
public virtual IMapping BuildMapping(Dialect.Dialect dialect)
{
return new Mapping(this);
#pragma warning disable CS0618
var mapping = BuildMapping();
#pragma warning restore CS0618
return new StaticDialectMappingWrapper(mapping, dialect);
}

/// <summary>
Expand Down Expand Up @@ -552,9 +547,8 @@ private void AddValidatedDocument(NamedXmlDocument doc)
public void AddDeserializedMapping(HbmMapping mappingDocument, string documentFileName)
{
if (mappingDocument == null)
{
throw new ArgumentNullException("mappingDocument");
}
throw new ArgumentNullException(nameof(mappingDocument));

try
{
var dialect = new Lazy<Dialect.Dialect>(() => Dialect.Dialect.GetDialect(properties));
Expand Down Expand Up @@ -749,9 +743,8 @@ public Configuration AddResource(string path, Assembly assembly)
public Configuration AddResources(IEnumerable<string> paths, Assembly assembly)
{
if (paths == null)
{
throw new ArgumentNullException("paths");
}
throw new ArgumentNullException(nameof(paths));

foreach (var path in paths)
{
AddResource(path, assembly);
Expand Down Expand Up @@ -938,19 +931,19 @@ public static bool IncludeAction(SchemaAction actionsSource, SchemaAction includ
/// <param name="dialect"></param>
public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect)
{
var mapping = BuildMapping(dialect);
SecondPassCompile();

var defaultCatalog = GetQuotedDefaultCatalog(dialect);
var defaultSchema = GetQuotedDefaultSchema(dialect);

var script = new List<string>();

var staticDialectMapping = new StaticDialectMappingWrapper(mapping, dialect);
foreach (var table in TableMappings)
{
if (table.IsPhysicalTable && IncludeAction(table.SchemaActions, SchemaAction.Export))
{
script.Add(table.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(table.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
script.AddRange(table.SqlCommentStrings(dialect, defaultCatalog, defaultSchema));
}
}
Expand All @@ -963,7 +956,7 @@ public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect)
{
foreach (var uk in table.UniqueKeyIterator)
{
string constraintString = uk.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema);
string constraintString = uk.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema);
if (constraintString != null)
{
script.Add(constraintString);
Expand All @@ -973,7 +966,7 @@ public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect)

foreach (var index in table.IndexIterator)
{
script.Add(index.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(index.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
}

if (dialect.SupportsForeignKeyConstraintInAlterTable)
Expand All @@ -982,7 +975,7 @@ public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect)
{
if (fk.IsGenerated(dialect) && IncludeAction(fk.ReferencedTable.SchemaActions, SchemaAction.Export))
{
script.Add(fk.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(fk.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
}
}
}
Expand All @@ -999,18 +992,18 @@ public string[] GenerateSchemaCreationScript(Dialect.Dialect dialect)
{
if (auxDbObj.AppliesToDialect(dialect))
{
script.Add(auxDbObj.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(auxDbObj.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
}
}

return script.ToArray();
}

private void Validate()
private void Validate(IMapping mapping)
{
ValidateEntities();
ValidateEntities(mapping);

ValidateCollections();
ValidateCollections(mapping);

ValidateFilterDefs();
}
Expand Down Expand Up @@ -1064,15 +1057,15 @@ private void ValidateFilterDefs()
}
}

private void ValidateCollections()
private void ValidateCollections(IMapping mapping)
{
foreach (var col in collections.Values)
{
col.Validate(mapping);
}
}

private void ValidateEntities()
private void ValidateEntities(IMapping mapping)
{
bool validateProxy = PropertiesHelper.GetBoolean(Environment.UseProxyValidator, properties, true);
HashSet<string> allProxyErrors = null;
Expand Down Expand Up @@ -1286,8 +1279,7 @@ protected virtual void ConfigureProxyFactoryFactory()
//http://nhibernate.jira.com/browse/NH-975

var ipff = Environment.BytecodeProvider as IInjectableProxyFactoryFactory;
string pffClassName;
properties.TryGetValue(Environment.ProxyFactoryFactoryClass, out pffClassName);
properties.TryGetValue(Environment.ProxyFactoryFactoryClass, out var pffClassName);
if (ipff != null && !string.IsNullOrEmpty(pffClassName))
{
ipff.SetProxyFactoryFactory(pffClassName);
Expand All @@ -1304,33 +1296,21 @@ protected virtual void ConfigureProxyFactoryFactory()
/// <returns>An <see cref="ISessionFactory" /> instance.</returns>
public ISessionFactory BuildSessionFactory()
{
var dynamicDialectMapping = mapping;
// Use a mapping which does store the dialect instead of instantiating a new one
// at each access. The dialect does not change while building a session factory.
// It furthermore allows some hack on NHibernate.Spatial side to go on working,
// See nhibernate/NHibernate.Spatial#104
mapping = new StaticDialectMappingWrapper(mapping);
try
{
ConfigureProxyFactoryFactory();
SecondPassCompile();
Validate();
Environment.VerifyProperties(properties);
Settings settings = BuildSettings();
var settings = BuildSettings();
var mapping = BuildMapping(settings.Dialect);
ConfigureProxyFactoryFactory();
SecondPassCompile();
Validate(mapping);
Environment.VerifyProperties(properties);

// Ok, don't need schemas anymore, so free them
Schemas = null;
// Ok, don't need schemas anymore, so free them
Schemas = null;

return new SessionFactoryImpl(
this,
mapping,
settings,
GetInitializedEventListeners());
}
finally
{
mapping = dynamicDialectMapping;
}
return new SessionFactoryImpl(this, mapping, settings, GetInitializedEventListeners());
}

/// <summary>
Expand Down Expand Up @@ -2363,13 +2343,13 @@ private static T[] AppendListeners<T>(T[] existing, T[] listenersToAdd)
/// <seealso cref="NHibernate.Tool.hbm2ddl.SchemaUpdate"/>
public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, IDatabaseMetadata databaseMetadata)
{
var mapping = BuildMapping(dialect);
SecondPassCompile();

var defaultCatalog = GetQuotedDefaultCatalog(dialect);
var defaultSchema = GetQuotedDefaultSchema(dialect);

var script = new List<string>(50);
var staticDialectMapping = new StaticDialectMappingWrapper(mapping, dialect);
foreach (var table in TableMappings)
{
if (table.IsPhysicalTable && IncludeAction(table.SchemaActions, SchemaAction.Update))
Expand All @@ -2378,11 +2358,11 @@ public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, IDatabaseMet
table.Catalog ?? defaultCatalog, table.IsQuoted);
if (tableInfo == null)
{
script.Add(table.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(table.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
}
else
{
string[] alterDDL = table.SqlAlterStrings(dialect, staticDialectMapping, tableInfo, defaultCatalog, defaultSchema);
string[] alterDDL = table.SqlAlterStrings(dialect, mapping, tableInfo, defaultCatalog, defaultSchema);
script.AddRange(alterDDL);
}

Expand Down Expand Up @@ -2410,7 +2390,7 @@ public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, IDatabaseMet
&& (!(dialect is MySQLDialect) || tableInfo.GetIndexMetadata(fk.Name) == null));
if (create)
{
script.Add(fk.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(fk.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
}
}
}
Expand All @@ -2420,7 +2400,7 @@ public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, IDatabaseMet
{
if (tableInfo == null || tableInfo.GetIndexMetadata(index.Name) == null)
{
script.Add(index.SqlCreateString(dialect, staticDialectMapping, defaultCatalog, defaultSchema));
script.Add(index.SqlCreateString(dialect, mapping, defaultCatalog, defaultSchema));
}
}
}
Expand All @@ -2444,9 +2424,9 @@ public string[] GenerateSchemaUpdateScript(Dialect.Dialect dialect, IDatabaseMet

public void ValidateSchema(Dialect.Dialect dialect, IDatabaseMetadata databaseMetadata)
{
var mapping = BuildMapping(dialect);
SecondPassCompile();

var staticDialectMapping = new StaticDialectMappingWrapper(mapping, dialect);
var defaultCatalog = GetQuotedDefaultCatalog(dialect);
var defaultSchema = GetQuotedDefaultSchema(dialect);

Expand All @@ -2473,7 +2453,7 @@ public void ValidateSchema(Dialect.Dialect dialect, IDatabaseMetadata databaseMe
}
else
{
validationErrors.AddRange(table.ValidateColumns(dialect, staticDialectMapping, tableInfo));
validationErrors.AddRange(table.ValidateColumns(dialect, mapping, tableInfo));
}
}
}
Expand Down
Loading