I have found some issues when using SubclassAttribute
with attribute mapping, for example, the base class is:
[Class(Schema = "public", Table="base_resources")]
[Discriminator(Column = "type")]
public class BaseResource {
[Id(Name = nameof(Id), Column = "id", Type = "long", Generator = "trigger-identity")]
public virtual long Id { get; set; }
[Property(Name=nameof(Name), Column = "name", Type = "string", Length = 32, NotNull = true)]
public virtual string Name { get; set; }
[Property(Name=nameof(Type), Column = "type", Type = "string", Length = 64, NotNull = true, Insert = false, Update = false)]
public virtual string Type { get; set; }
}
The generated xml mapping is correct :
<class table="base_resources" schema="public" name="NHibernate.Extensions.UnitTest.TestDb.BaseResource, NHibernate.Extensions.UnitTest">
<id name="Id" column="id" type="long" generator="trigger-identity" />
<discriminator column="type" />
<property name="Name" type="string" column="name" length="32" not-null="true" />
<property name="Type" type="string" column="type" length="64" not-null="true" update="false" insert="false" />
</class>
And I have a sub class which is:
[Subclass(DiscriminatorValue = "data_api", ExtendsType = typeof(BaseResource), Lazy = true)]
public class DataApi : BaseResource {
[Join(Schema = "public", Table = "data_apis", Fetch = JoinFetch.Select)]
[Key(Column = "id")]
[Property(Name = nameof(Statement), Column = "statement", Length = 128, NotNull = true)]
public virtual string Statement { get; set; }
[Property(Name = nameof(Parameters), Column = "parameters", Length = 128, NotNull = true)]
public virtual string Parameters { get; set; }
}
This looks correct, but the xml mapping generated is not correct:
<subclass discriminator-value="data_api" extends="NHibernate.Extensions.UnitTest.TestDb.BaseResource, NHibernate.Extensions.UnitTest" lazy="true" name="NHibernate.Extensions.UnitTest.TestDb.DataApi, NHibernate.Extensions.UnitTest">
<property name="Parameters" column="parameters" length="128" not-null="true" />
<join table="data_apis" schema="public" fetch="select">
<key column="id" />
<property name="Statement" column="statement" length="128" not-null="true" />
</join>
</subclass>
The property
element for Parameters
goes out of the join
element, which should be inside the join
element.
Then I change the code for DataApi
, move all of the PropertyAttribute
to one property, like this:
[Subclass(DiscriminatorValue = "data_apis", ExtendsType = typeof(BaseResource), Lazy = true)]
public class DataApi : BaseResource {
[Join(Schema = "public", Table = "data_apis", Fetch = JoinFetch.Select)]
[Key(Column = "id")]
[Property(Name = nameof(Statement), Column = "statement", Length = 128, NotNull = true)]
[Property(Name = nameof(Parameters), Column = "parameters", Length = 128, NotNull = true)]
public virtual string Statement { get; set; }
public virtual string Parameters { get; set; }
}
Then the xml mapping generated is corrected now, looks like:
<subclass discriminator-value="data_api" extends="NHibernate.Extensions.UnitTest.TestDb.BaseResource, NHibernate.Extensions.UnitTest" lazy="true" name="NHibernate.Extensions.UnitTest.TestDb.DataApi, NHibernate.Extensions.UnitTest">
<join table="data_apis" schema="public" fetch="select">
<key column="id" />
<property name="Parameters" column="parameters" length="128" not-null="true" />
<property name="Statement" column="statement" length="128" not-null="true" />
</join>
</subclass>
But is the sub class DataApi
has a many-to-one
mapping like this:
[Subclass(DiscriminatorValue = "data_api", ExtendsType = typeof(BaseResource), Lazy = true)]
public class DataApi : BaseResource {
[Join(Schema = "public", Table = "data_apis", Fetch = JoinFetch.Select)]
[Key(Column = "id")]
[ManyToOne(Name = "DataSource", Column = "data_source_id", ClassType = typeof(DataSource), NotFound = NotFoundMode.Ignore, Lazy = Laziness.Proxy, Fetch = FetchMode.Select)]
[Property(Name = nameof(Statement), Column = "statement", Length = 128, NotNull = true)]
[Property(Name = nameof(Parameters), Column = "parameters", Length = 128, NotNull = true)]
public virtual DataSource DataSource { get; set; }
public virtual string Statement { get; set; }
public virtual string Parameters { get; set; }
}
The xml mapping generated is not correct again, like this:
<subclass discriminator-value="data_api" extends="NHibernate.Extensions.UnitTest.TestDb.BaseResource, NHibernate.Extensions.UnitTest" lazy="true" name="NHibernate.Extensions.UnitTest.TestDb.DataApi, NHibernate.Extensions.UnitTest">
<join table="data_apis" schema="public" fetch="select">
<key column="id" />
<many-to-one name="DataSource" class="Beginor.GisHub.DataServices.Data.DataSource, Beginor.GisHub.DataServices" column="data_source_id" fetch="select" lazy="proxy" not-found="ignore" />
</join>
</subclass>
There is only one many-to-one
element , other properties is not generated.
But if I move the ManyToOne
after Property
, like this:
[Subclass(DiscriminatorValue = "data_api", ExtendsType = typeof(BaseResource), Lazy = true)]
public class DataApi : BaseResource {
public virtual DataSource DataSource { get; set; }
[Join(Schema = "public", Table = "data_apis", Fetch = JoinFetch.Select)]
[Key(Column = "id")]
[Property(Name = nameof(Statement), Column = "statement", Length = 128, NotNull = true)]
[Property(Name = nameof(Parameters), Column = "parameters", Length = 128, NotNull = true)]
[ManyToOne(Name = "DataSource", Column = "data_source_id", ClassType = typeof(DataSource), NotFound = NotFoundMode.Ignore, Lazy = Laziness.Proxy, Fetch = FetchMode.Select)]
public virtual string Statement { get; set; }
public virtual string Parameters { get; set; }
}
Then the xml mapping generated is correct again, like this:
<subclass discriminator-value="data_api" extends="NHibernate.Extensions.UnitTest.TestDb.BaseResource, NHibernate.Extensions.UnitTest" lazy="true" name="NHibernate.Extensions.UnitTest.TestDb.DataApi, NHibernate.Extensions.UnitTest">
<join table="data_apis" schema="public" fetch="select">
<key column="id" />
<property name="Parameters" column="parameters" length="128" not-null="true" />
<property name="Statement" column="statement" length="128" not-null="true" />
<many-to-one name="DataSource" class="Beginor.GisHub.DataServices.Data.DataSource, Beginor.GisHub.DataServices" column="data_source_id" fetch="select" lazy="proxy" not-found="ignore" />
</join>
</subclass>
I think that's very strange behavior,is there any who can tell me the magic?
And I think SubclassAttribute
should be used the same way as ClassAttribute
, like this:
[Subclass(DiscriminatorValue = "data_api", ExtendsType = typeof(BaseResource), Lazy = true)]
[Join(Schema = "public", Table = "data_apis", Fetch = JoinFetch.Select)]
[Key(Column = "id")]
public class DataApi : BaseResource {
[ManyToOne(Name = "DataSource", Column = "data_source_id", ClassType = typeof(DataSource), NotFound = NotFoundMode.Ignore, Lazy = Laziness.Proxy, Fetch = FetchMode.Select)]
public virtual DataSource DataSource { get; set; }
[Property(Name = nameof(Statement), Column = "statement", Length = 128, NotNull = true)]
public virtual string Statement { get; set; }
[Property(Name = nameof(Parameters), Column = "parameters", Length = 128, NotNull = true)]
public virtual string Parameters { get; set; }
}
Is anyone who can improve it?