Nous avons une vieille application asp.net avec nhibernate, que nous étendons et améliorons. NHibernate utilisé était assez ancien (1.0.2.0), nous avons donc décidé de passer à (2.1.2) pour les nouvelles fonctionnalités. Les fichiers HBM sont générés via un modèle personnalisé avec MyGeneration. Tout s'est bien passé, sauf pour une chose.Migration de Nhibernate de 1.0.2.0 à 2.1.2 et problèmes d'enregistrement plusieurs-à-un
Disons que nous avons des objets Blog et Post. Le blog peut contenir de nombreux messages, de sorte que Post aura des relations plusieurs-à-un. En raison du mode de fonctionnement de cette application, la relation n'est pas effectuée via les clés primaires, mais via la colonne Blog.Reference.
Exemples de fichiers de mapings et .cs:
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id" column="Id" type="Guid">
<generator class="assigned"/>
</id>
<property column="Reference" type="Int32" name="Reference" not-null="true" />
<property column="Name" type="String" name="Name" length="250" />
</class>
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id" column="Id" type="Guid">
<generator class="assigned"/>
</id>
<property column="Reference" type="Int32" name="Reference" not-null="true" />
<property column="Name" type="String" name="Name" length="250" />
<many-to-one name="Blog" column="BlogId" class="SampleNamespace.BlogEntity,SampleNamespace" property-ref="Reference" />
</class>
et fichiers classe
class BlogEntity
{
public Guid Id { get; set; }
public int Reference { get; set; }
public string Name { get; set; }
}
class PostEntity
{
public Guid Id { get; set; }
public int Reference { get; set; }
public string Name { get; set; }
public BlogEntity Blog { get; set; }
}
Maintenant, supposons que que j'ai un blog avec Id 1D270C7B-090D-47E2-8CC5-A3D145838D9C et avec référence 1
Dans la vieille NHibernate telle chose était possible:
//this Blog already exists in database
BlogEntity blog = new BlogEntity();
blog.Id = Guid.Empty;
blog.Reference = 1; //Reference is unique, so we can distinguish Blog by this field
blog.Name = "My blog";
//this is new Post, that we are trying to insert
PostEntity post = new PostEntity();
post.Id = Guid.NewGuid();
post.Name = "New post";
post.Reference = 1234;
post.Blog = blog;
session.Save(post);
Cependant, dans une nouvelle version, je reçois une exception qui ne peut pas insérer NULL dans Post.BlogId. Comme je comprends, dans l'ancienne version, pour nhibernate il suffisait d'avoir un champ Blog.Reference, et il pouvait récupérer l'entité par ce champ, et l'attacher à PostEntity, et lors de l'enregistrement de PostEntity, tout fonctionnerait correctement. Et si je comprends bien, NHibernate essaie seulement de récupérer par Blog.Id.
Comment résoudre ce problème? Je ne peux pas changer de design de DB, je ne peux pas non plus attribuer d'identifiant à BlogEntity, car les objets sont hors de mon contrôle (ils sont pré-remplis comme des "ojbects" génériques comme ça)
Malheureusement, je ne peux pas faire comme ça. Disons que j'ai plus de 50 objets différents, et ils entrent par la méthode "générique" démodée - disons InsertEntity (entité objet). Et l'entité pourrait être Blog, pourrait être Post, pourrait être utilisateur, pourrait être autre chose ... Et le pire - je ne peux pas changer cette méthode, parce que c'est hors de mon contrôle – Meska
Je ne comprends toujours pas pourquoi vous ne pouvez pas fais le. Vous avez une session.Enregistrez (post) dans votre code d'origine, ce n'est pas différent dans mon code. Et le code que j'ai ajouté ne fait qu'une requête pour rechercher l'entité Blog par sa référence. Alors, quel est exactement le problème? Si le problème est que vous ne pouvez pas changer le code, je vous suggère de ne pas introduire une nouvelle bibliothèque NHibernate. –
Ce scénario Blog/Post est juste une preuve de concept de ce qui se passe. C'est beaucoup plus compliqué, et la méthode save est la plus proche: InserEntity (entité objet) { // effectue un traitement. entité est vraiment générique session.save } et je ne peux pas modifier la signature d'InserEntity (entité objet). De toute façon, merci pour l'aide :), et il semble que nous allons sauter l'introduction de nhibernate nouveau, s'il n'y a pas de solution possible dans quelques jours – Meska