J'ai une classe d'envoi qui regroupe une classe FreightDateTime. En même temps, la classe FreightDateTime est également agrégée par la classe GoodsItem. De la même manière, FreightDateTime est associé à un certain nombre d'autres classes que j'ai omises pour l'instant.NHibernate: la relation plusieurs-à-plusieurs ne parvient pas à enregistrer les objets enfants en premier (soit: "ne peut pas insérer de null" ou: "objet transitoire")
Pour éviter une base de données FreightDateTime avec une clé étrangère ConsignmentId, une clé étrangère GoodsItemId, etc., j'ai décidé que l'association devrait être plusieurs-à-plusieurs. De cette façon, NHibernate génère une table d'association pour chaque relation (ConsigmentFreightDateTimes, GoodsItemFreightDateTimes), ce qui est plus logique. Ainsi, dans le fichier de mappage, l'association recherche, par exemple, dans le fichier de mappage. comme ceci:
<bag name="DateTimes" table="FreightDateTimes" lazy="false" cascade="all">
<key column="ConsignmentId"/>
<many-to-many class="Logistics.FreightDateTime, Logistics" column="DateTimeId" />
</bag>
Réglage cascade "tous les" rendements:
System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'DateTimeId', table 'LogiGate.dbo.FreightDateTimes'; column does not allow nulls. INSERT fails.
Réglage cascade à "none" rendements:
NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Logistics.FreightDateTime
Dans les deux cas, cela signifie que NHibernate tente pour enregistrer l'instance Consignment, bien que les instances FreightDateTime enfant n'aient pas été enregistrées. Dans le premier cas, la clé étrangère est toujours 'nulle', qui ne peut donc pas être insérée dans la table résultante, et dans le second cas, NHibernate est conscient que l'instance n'a pas encore été sauvegardée, et lève donc l'exception. Donc, la question est de savoir comment je peux obtenir NHibernate pour enregistrer toutes les instances enfants en premier, sans lui dire explicitement de le faire. J'ai le pressentiment qu'autoriser des valeurs nulles sur la colonne DateTimeId ferait l'affaire, mais je pense que ce n'est ni souhaitable ni possible.
L'ajout d'un sac inverse au mappage FreightDateTime demandera à NHibernate d'avoir également une propriété IList correspondante dans la classe FreighDateTime. Mon but est d'éviter de référencer FreightDateTime à Consignment au niveau de la classe et de la table, car FreightDateTime ne devrait pas avoir besoin de "savoir" quoi que ce soit sur les objets qui le possèdent. Comment cela pourrait-il être mis en œuvre? –
Je crois qu'il n'y a pas moyen de contourner cela. Vous devez avoir créé le sac inverse pour que votre mappage fonctionne comme vous le souhaitez. Ce que NHibernate vous permet est de mapper le sac à un membre privé au lieu d'une propriété publique (attribut access = "field") qui ne serait pas accessible depuis l'extérieur de l'implémentation de l'entité. Si vous persistez à ne pas cartographier l'inverse, essayez simplement de voir si cela fonctionne. Ensuite, vous pouvez le faire fonctionner jusqu'à ce que vous trouviez la solution «parfaite» pour vous (s'il y en a une). – tolism7
Merci. Je pense que je préférerais avoir beaucoup de relations un-à-plusieurs, ce qui se traduira probablement par le fait que la table FreightDateTimes se réfère à beaucoup d'autres tables qui ne sont pas liées entre elles, mais que ce soit pour l'instant. J'ai également regardé composite-element et many-to-any, mais ceux-ci sont destinés à différentes situations. Ou que penses-tu? –