I'm trying to work through this issue where the subclass contains a set of properties however two of the properties do not exist in the referenced table.
These two properties exist in an Extension table that has FKs back to the base table. I'm unsure how to modify this xml to support the first joined subclass and addition of another join for the Extension table.
I tried to simply add another joined-subclass for the Extension table, however since the class name was the same, the mapping were invalid.
<joined-subclass name="SESProgramAssociationAggregate.SESProgramAssociation" table="SESProgramAssociation" lazy="false">
<key>
<column name="BeginDate" />
<column name="EOId" />
<column name="PEOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="UDI" />
</key>
<!-- PK properties -->
<property name="UDI" column="UDI" type="int" not-null="true" insert="false" />
<property name="ProgramTypeId" column="ProgramTypeId" type="int" not-null="true" insert="false" />
<property name="PEOrganizationId" column="PEOrganizationId" type="int" not-null="true" insert="false" />
<property name="BeginDate" column="BeginDate" type="date" not-null="true" insert="false" />
<property name="ProgramName" column="ProgramName" type="string" length="60" not-null="true" insert="false" />
<property name="EOId" column="EOId" type="int" not-null="true" insert="false" />
<!-- Properties -->
<property name="Eligibility" column="Eligibility" type="bool" />
<property name="SESDescriptorId" column="SESDescriptorId" type="int" not-null="true" />
<property name="SEHoursPerWeek" column="SEHoursPerWeek" type="decimal" />
<property name="HoursPerWeek" column="HoursPerWeek" type="decimal" />
<property name="MultiplyD" column="MultiplyD" type="bool" />
<property name="MFragile" column="MFragile" type="bool" />
<property name="LastEvalDate" column="LastEvalDate" type="date" />
<property name="ReviewDate" column="ReviewDate" type="date" />
<property name="BeginDate" column="BeginDate" type="date" />
<property name="EndDate" column="EndDate" type="date" />
<property name="EventCode" column="EventCode" type="int" />
<property name="WrittenConsentDate" column="WrittenConsentDate" type="date" />
</joined-subclass>
The final query that is generated fails because it attempts to reference the EventCode and WrittenConsentDate from the SESProgramAssociation table where they do not exist. They actually exist in the Extension table.
I'm not sure how to modify this xml to point those fields to the Extension table so the generated query actually pulls them from that table instead of the wrong one. Any help is greatly appreciated, this is my first experience with NHiberate and needless to say, it's not been fun!
After advice from Frédéric, I updated but got this error:
An exception of type 'NHibernate.MappingException' occurred in NHibernate.dll but was not handled in user code
Additional information: EdFi.Ods.Entities.NHibernate.Mappings.SqlServer.StudentProgramAssociationBase.hbm.xml(79,8): XML validation error: The element 'joined-subclass' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'join' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'property, many-to-one, one-to-one, component, dynamic-component, properties, any, map, set, list, bag, idbag, array, primitive-array, joined-subclass, loader, sql-insert, sql-update, sql-delete, resultset, query, sql-query' in namespace 'urn:nhibernate-mapping-2.2'.
Your second table should not be mapped as another joined-subclass
, since it does not match a subclass in your domain model.
It should be mapped either as a standalone Extension
entity, with the extended entity referencing it as a one-to-one
related entity.
Or you can use the join
mapping for having a single entity in your domain model. But the join
mapping is not allowed on subclass
, so you would have to use it on your base class, if you can add to it those properties. Adjusting your pastebin mapping linked in comment:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Entities.NHibernate"
namespace="Entities.NHibernate.SPAssociationAggregate"
default-access="property">
<!-- Class definition -->
<class name="SPAssociationBase" table="SPAssociation" lazy="false">
<!-- Composite primary key -->
<composite-id>
<key-property name="BeginDate" type="date" />
<key-property name="OrganizationId" />
<key-property name="ProgramOrganizationId" />
<key-property name="ProgramName" length="60" />
<key-property name="ProgramTypeId" />
<key-property name="SUSI" />
</composite-id>
<!-- Optimistic locking for aggregate root -->
<version name="LastModifiedDate" type="timestamp" />
<!-- Transient state detection -->
<property name="CreateDate" type="DateTime" />
<!-- Unique Guid-based identifier for aggregate root -->
<property name="Id" />
<!-- Properties -->
<property name="EndDate" type="date" />
<property name="ReasonExitedDescriptorId" />
<property name="ServedOutsideOfRegularSession" />
<!-- Collections -->
<bag name="SPAssociationServices" cascade="all-delete-orphan" inverse="true" lazy="false">
<key>
<column name="BeginDate" />
<column name="OrganizationId" />
<column name="ProgramOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="SUSI" />
</key>
<one-to-many class="SPAssociationServiceForBase" />
</bag>
<!-- Extended properties -->
<join table="SSEPAssociationExtension" optional="true">
<key>
<column name="BeginDate" />
<column name="OrganizationId" />
<column name="ProgramOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="SUSI" />
</key>
<property name="EventCode" />
<property name="WrittenConsentDate" />
</join>
<!-- Derived classes -->
<joined-subclass name="SESProgramAssociationAggregate.SESProgramAssociation" table="SESProgramAssociation" lazy="false">
<key>
<column name="BeginDate" />
<column name="OrganizationId" />
<column name="ProgramOrganizationId" />
<column name="ProgramName" />
<column name="ProgramTypeId" />
<column name="SUSI" />
</key>
<!-- Properties -->
<property name="IdeaEligibility" />
<property name="DescriptorId" />
<property name="HoursPerWeek" />
<property name="SHoursPerWeek" />
<property name="MultiplyD" />
<property name="MFragile" />
<property name="LastEvaluationDate" type="date" />
<property name="ReviewDate" type="date" />
<property name="BeginDate" type="date" />
<property name="EndDate" type="date" />
<property name="EventCode" />
<property name="WrittenConsentDate" type="date" />
</joined-subclass>
</class>
</hibernate-mapping>
Side notes:
GetHashCode
and Equals
for them, ... <id>
, and so you should not have any need to map them again in the joined subclass. lazy
loading is not an usual practice with NHibernate. Lazy loading with NHibernate can benefit of batched loadings, which render it quite efficient. See my answer here for more details.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.