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