Well, a very interesting idea - I mean, to keep a parallel data in the
database. Worth looking at.

As for hiding, I may agree that this is an anti-pattern... however I
hide it behind a repository anyway (because those are pretty weird
data structures and actions I need to perform to get them working, and
because I need my Item refer to other Products), so why not to make it
right and easy to the end...

On 7 сен, 22:02, Markus Zywitza <[email protected]> wrote:
> A persistent type is simply a class mapped to a table with NH. The idea is
> that you don't save just a string with the legacy item id, but a real class
> that contains the legacy item id among other (cached) data of the original
> item data, depending on stability of the original data. If you decide to
> move the items into your main database, you can simply extend this class.
> Until then you have to use an anti-corruption-layer to mediate between the
> item class in your model and the legacy datastore.
>
> Trying to hide such an important issue like legacy datastores within
> NHibernate is rather an anti-pattern.
>
> -Markus
>
> 2009/9/7 queen3 <[email protected]>
>
>
>
> > Sorry but I don't understand what do you mean by "persistent type"? Is
> > it something like Active Record - a class that has .Load/.Save? I
> > don't see how it's different from creating repository inside
> > IUserType.
>
> > And the problem is not transaction-safe creation of a single Item. The
> > complete transaction is like:
> > 1. Create all product.Items on web service
> > 2. Save product into DB now with newly generated Item IDs
> > As you can see from the transaction I have to rollback all created
> > Items if some of them failed to created or product failed to save to
> > database.
>
> > By the way I found a similar question here and Ayende highly
> > recommending not doing so:
> >http://markmail.org/message/yixji3gsy4ou4jjj
> >http://markmail.org/message/o3vx6bdu5uusmu66
>
> > Still this seems to me a very promising solution...
>
> > On 7 сен, 20:22, Markus Zywitza <[email protected]> wrote:
> > > 5. Create a persistent type for Item and reference it. For what to
> > include
> > > into the type, there is no silver bullet; you have to decide case by
> > case,
> > > as this also depends on change frequency and required performance.
> > > To create and update instances of the Item type from the web service use
> > an
> > > anti-corruption-layer, embedded into a repository implementation.
>
> > > -Markus
>
> > > 2009/9/7 queen3 <[email protected]>
>
> > > > I have a Product class for which I need IList<Item> Items property.
> > > > However, I can only get Item from a legacy external repository (web
> > > > service) by string id. So I came with these solutions:
>
> > > > 1. Use IList<string> ItemIds and do itemRepository.Get(id) when needed
> > > > in my client code (controllers). Too manual and not very nice. And it
> > > > would be nice to hide the fact that Item is not part of the persisten
> > > > store... what if in future we'll finally move Items to the database?
> > > > Rewrite all the code? Don't want that.
>
> > > > 2. Use IUserType and load/save object inside NullSafeSet/Get:
> > > >      public object NullSafeGet(IDataReader rs, string[] names, object
> > > > owner)
> > > >      {
> > > >         return new ItemRepository().Get((string)
> > > > NHibernateUtil.String.NullSafeGet(rs, names[0]));
> > > >      }
> > > >      public void NullSafeSet(IDbCommand cmd, object value, int index)
> > > >      {
> > > >         new ItemRepository().Save((Item)value);
> > > >         cmd.Parameters[index] = ((Item)value).Id;
> > > >      }
> > > > Above (is simplifed but) should probably work very well (though I'm
> > > > not expert in IUserType). There's one issue, though... what do I do if
> > > > an error occured and I need to rollback changes to Items? There's no
> > > > notion of transactions in IUserType.
> > > > There's problem with "new ItemRepository()" which is not nice, see (4)
> > > > for why.
>
> > > > 3. So I can do this work in the place where I have access to
> > > > transactions: ProductRepository.
> > > > public Product BeginTransaction() // actually
> > > > DbContext.BeginTransaction() but it doesn't matter
> > > > {
> > > >    itemRepository.BeginTransaction();
> > > > }
> > > > public Product Get(int id)
> > > > {
> > > >    var product = Session.Get(id);
> > > >    foreach (var item in product.Items)
> > > >         itemRepository.SaveOrUpdate(item);
> > > > }
> > > > public void Rollback() // actually DbContext.Rollback() but it doesn't
> > > > matter
> > > > {
> > > >   itemRepository.Rollback();
> > > > }
> > > > Notice that it also makes it easier to couple ProductRepository/
> > > > ItemRepository together since I can inject IItemRepository into
> > > > ProductRepository constructor, not just use "new ItemRepository()"
> > > > inside IUserType.
> > > > But, this way is a bit harder because I
>
> > > > 4. Somehow combine these ways? From what I see, the (4) does not
> > > > conflict with (3), i.e. if ProductRepository correctly align its
> > > > transactions with ItemRepository, we're safe? So, IUserType will be
> > > > responsible for loading/saving Item instances (no foreach(item)
> > > > needed), while ProductRepository will deal with transaction failure
> > > > and align calls to itemRepository.BeginTransaction()/Rollback()? Will
> > > > it work? I think NO because inside IUserType I use "new ItemRepository
> > > > ()"... so unless I have singlton factory IUserType and
> > > > ProductRepository will have different ItemRepository instances/
> > > > sessions/transactions...
>
> > > > So, did anyone experienced the same problem? What is the best solution/
> > > > practices here?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to