« Gartner ne conseille pas de migrer à Office 2007DataBinding dans ASP.Net 2.0 et NHibernate, pas de panique »

11 commentaires

Commentaire de: Tom [Visiteur]
Et donc pour une application dans laquelle les objets ont des relations complexes les uns avec les autres... ça semble infaisable en pratique... Me trompe-je?

Tom

28.04.06 @ 22:08
Commentaire de: Sami [Visiteur] · http://www.dotnetguru.org
« vous ne pouvez pas faire d’update sur cet objet car il est différent de celui qui existe déjà dans votre session NHib »
Pour éviter ce pb, il suffit de faire un session.reconnect(). J'avoue ne pas trop avoir compris après le sens de la copie d'objet. Quid des associations? dans l'exemple de l'article tous les types sont primitifs, que faire en cas de types complexes liés, il va me falloir récursivement copier les associations ?

Sami
28.04.06 @ 22:52
Commentaire de: Sami [Visiteur] · http://www.dotnetguru.org
oups... désolé Tom j'avais pas vu ton commentaire, si c'est pas être psychologiquement connecté ça :-)
28.04.06 @ 22:55
Commentaire de: Guillaume Saint Etienne [Membre] Email · http://twitter.com/guillaume_agile
malheureusement Session.Reconnect n'est pas la solution. Son appel lève une exception:
Exception Details: NHibernate.HibernateException: session already connected

par contre oui, ceci n'est pas fait pour les objets portant des associations. Dans mon cas, il s'agit d'editer avec un DetailView un objet possédant des données scalaires. Il est prudent de s'en tenir là. Et de gérer les associations à part (avec un autre composant graphique par exemple).

Il faudrait aller plus loin, et voir comment se comporte le 2-way data binding avec les éléments associés. A mon avis, ca ne doit pas être superbe et il doit falloir encore du "hand-coding". Ce sera la suite de mon étude.

Ceci dit, merci pour vos commentaires. Sachant que je vous livre ici non pas LA solution, mais une solution possible.
29.04.06 @ 03:03
Commentaire de: yartz [Visiteur]
Ca écorne un peu la réputation d'élégance d'Hibernate tout ça. En gros, on a un mapping relationnel objet state of the art, qui respecte tous les patterns, fait de l'IOC, de l'AOP, et probablement trois ou quatre autres TLA, mais il faut faire par dessus du mapping objet/objet et des copies dans tous les coins parce que NHibernate n'a pas été pensé pour faire de l'ASP .Net ?
29.04.06 @ 10:17
Commentaire de: Tom [Visiteur]
Je serais tenté de dire que c'est le data binding bidirectionnel qui est un peu simpliste, ou plutôt qui a été conçu pour visualiser et mettre à jour des informations "à plat", pas des graphes de données (xml ou objet).

La solution pourrait être de s'appuyer sur un framework de présentation Web 2.0 qui rapatrie la structure de données complexe côté client et en modifie le contenu directement en mémoire avant de la re-transférer sur le serveur pour mise à jour. J'ai mis en oeuvre une petite appli qui ressemble à ça basée sur les EJB 3 et DWR il y a quelques temps, c'était parfait en termes de productivité. Certains frameworks .NET doivent offrir ce genre de possibilités (pas creusé pour le moment), bien plus intéressantes que le binding "bidi" côté serveur en ASP.NET 2.0 classique.

Tom
29.04.06 @ 11:08
Commentaire de: sami [Membre] Email
Ok je comprend mieux ce que tu cherches à faire. Je vais essayer de résumer :
- Tu veux faire une sorte de Master/Detail avec le même objet
- Or, (et c'est logique) ASP.NET recréé non seulement l'arbre des controls mais les ObjectDataSource associés
- Ta session est du type "Session Longue", du coup le cache de premier niveau est tout le temps actif (et tu n'evict() pas les objets)

Du coup, c'est tout à fait normal d'avoir un tel comportement. Qui plus est, Nhibernate n'en est pas la cause, tu aurais utilisé n'importe quel outil de mapping, le résultat aurait été à mon avis le même. Le mode Web fait que les graphes d'objets sont reconstruits à chaque requête. Et comme une même session Hibernate ne peut posséder deux références différentes pour une même clef, l'outil lève une exception.

Par contre ta solution me semble assez inadaptée. Pourquoi faire un lock et copier des objets, alors qu'un simple lock sur modifiedData aurait suffit ou même mieux SaveOrUpdateCopy() ?

1)
[DataObjectMethod(DataObjectMethodType.Update)]
public bool Modify2(X.DataEntityObjects.TRestaurants modifiedData)
{
nhibsession.lock(modifiedData, LockMode...)
}

2) session.SaveOrUpdateCopy(modifiedData) (il copie l'objet passé en paramètre avec celui attaché en session mais n'attache jamais le paramètre)...

Et puis, si on veut encore une autre solution (celle que je préfère) : Il vaut mieux ne jamais utiliser le mode Long lived Session sur du Web et faire de l'optimistic locking.

Sami
ps: guillaume,pourrais tu mettre un lien sur les sources si c'est possible?
29.04.06 @ 11:22
Commentaire de: Guillaume Saint Etienne [Membre] Email · http://twitter.com/guillaume_agile
alors... tout cela n'est pas simple, alors qu'il s'agit des operations de Databinding les plus courament pratiquées.

Oui en effet, SaveOrUpdateCopy que j'ai tenté d'utiliser semblait le plus approprié;
mais il ne marche pas dans mon cas car mon objet de données TRestaurant possède des relations avec d'autres objets.
Du coup une exception est levée: object references an unsaved transient instance - save the transient instance before flushing: NomDeLObjetLieParTelation .

Sachant que dans mon detailview, je ne veux que travailler sur les données scalaires, par les données résultantes des objets liés; il y aura d'autres IHM pour ca. Sinon on se tape la liaison à l'infini de toutes les entités dépendantes. Et on a une IHM hyper-contrainte par la couche de persistance et ce n'est pas le but non plus.

Ok, le problème peut venir aussi du schema de mapping et la facon dont sont exploitées les relations. Activer le lazy sur le mode "extra" serait une solution? Debrancher les objets entre eux par le mapping? (Je n'utilise pas le mode cascade).
Il me parait peu sensé de devoir adapter un schema O/R aux nécessités des opérations de domaine. Cela devrait pouvoir se regler autrement.

Mon idée etait de contrôler le databinding donné par défaut, d'une manière acceptable pour lui (le couple NHib/Webforms) faire faire exactement ce que l'on souhaite et qu'il n'en fasse pas trop.
D'où l'idée de se ré-approprier la partie mise à jour de données en faisant soi même le choix des données à faire updater par NHib ( et pas le laisser tout faire tout seul puisque ca se passe mal ).


PS: les captures d'écran, sources et le détail du projet viennent avec l'article en préparation.
04.05.06 @ 12:48
Commentaire de: Bertrand Le Roy [Visiteur] · http://weblogs.asp.net/bleroy
Je peux poser une question idiote? Pourquoi ton UI parle directement à ta DAL? Ça devrait pas plutôt causer à ta BL?
05.05.06 @ 00:57
Commentaire de: Denis [Visiteur] · http://www.ergotinfo.fr

Je viens de tomber sur ce problème sur un prototype ObjectDataSource + Castle ActiveRecord + Nhibernate. Très ennuyeux. L'origine en est que pour un Update l'ObjectDataSource appel le constructeur par défaut et ne nous laisse jamais la main pour substituer notre propre constructeur ou appeler une fonction sur une éventuelle Factory.


J'ai cru un moment que l'event OnObjectCreating pourrait nous sauver, mais il ne permet que de spécifier la Facade de l'accès aux objects quand les fonctions d'accès (SelectMethod...) sont non statiques, et non les objets eux-mêmes.


Je ne vois pas de solution satisfaisante mais je n'ai pas tout essayé (les paramètres du style UpdateParameters ?). Je suis preneur de tout workaround...

07.05.06 @ 12:50
Commentaire de: Guillaume Saint Etienne [Membre] Email · http://twitter.com/guillaume_agile
pour répondre à Bertrand Le Roy: il est évident que nous parlons ici entre grandes personnes et que, bien sûr, l'UI parle à des objets métiers ou de domaine (le CRUD fait-il partie du metier? débat!).

Mais comme les colonnes de publication dans les blogs doivent rester courtes, je ne vous ai pas exposé l'architecture totale de ma solution. Ceci sera expliqué dans l'article complet sur NHibernate que je prépare.

Pour le moment, je montre directement le code des opérations de la DAL, car elle travaille tout de même, en dessous de toute couche métier, donc il faut bien s'en occuper et c'est à son niveau des exceptions sont levées et empechait ma solution "naive" de fonctionner.
07.05.06 @ 14:06

Laisser un commentaire


Votre adresse email ne sera pas révélée sur ce site.

Votre URL sera affichée.
(Les retours à la ligne deviennent des <br />)
(Nom, e-mail & site Web)
(Autoriser les utilisateurs à vous contacter par un formulaire de message (votre adresse email ne sera not révélée.))
This is a captcha-picture. It is used to prevent mass-access by robots.
Please enter the characters from the image above. (case insensitive)