how to stop NH inserting new entites when I add an existing entity to a collection

14 views
Skip to first unread message

Davec

unread,
Nov 30, 2011, 6:28:19 AM11/30/11
to nhusers
Hi folks,
I have a very primative business object, with a single property: URL.
It's a value object so if to URLs are the same I want NH to consider
them as so and not insert another record into the DB when there is
already ready one in there for it.

To elborate then, I have code which works which looks like:

PostRollAdvert existingAdvert = _postRollAdvertRepository.Find(t =>
t.URL == URL).SingleOrDefault();
if (existingAdvert != null)
pw.PostRollAdverts.Add(existingAdvert); //add existing
else
{
PostRollAdvert newAdvert = new PostRollAdvert() { URL =
adFromFrontend.URL };
pw.PostRollAdverts.Add(newAdvert);
}

but I want to not have to check if it already exists in the DB if
possible by just calling pw.PreRollAdverts.Add(advert);

and letting nhibernate figure out that the advert which I'm attempting
to add to the parents collection is itself already in the DB so dont
add it again just update the association column or table. I have
implemented equals in my advert object but it's does not seem to be
getting hit. It looks like the following:

//implemented so NH will not attempt to insert new 'duplicate' ads
public override bool Equals(object obj)
{
if (obj == null)
return false;

RollAdvert ra = obj as RollAdvert;
if (ra == null)
return false;

//adverts are equal if there URLs match
return URL == ra.URL;
}

so do I have to explicity check if something is already in the DB or
call I just do something like pw.PreRollAdverts.Clear() and then add
in everything to the collection. I have cascade-delete-orphan set as
the cascade option if that's important.

Thanks in advance.

Oskar Berggren

unread,
Nov 30, 2011, 8:30:02 AM11/30/11
to nhu...@googlegroups.com
What is pw?
What is pw.PreRollAdverts? Or PostRollAdverts? (you mention both).
How are they mapped and what is relevant pieces of the database structure?

The answers to the questions above will affect this, but here are some
starting comments:
If you add the same value object to the same collection twice,
NHibernate will save it twice, otherwise objects would just disappear.
So what you want then is to use a collection that will ensure
uniqueness, i.e. a "set" type collection. The other important thing to
consider is how NHibernate can see the difference between saved and
unsaved instances, see "unsaved-value".

/Oskar


2011/11/30 Davec <davep...@gmail.com>:

> --
> You received this message because you are subscribed to the Google Groups "nhusers" group.
> To post to this group, send email to nhu...@googlegroups.com.
> To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.
>
>

Jason Meckley

unread,
Nov 30, 2011, 12:36:53 PM11/30/11
to nhu...@googlegroups.com
I believe you are talking about sets. you have 2 options.
1. use a set instead of a list/bag. by definitions sets will contain uniquely identified objects
if(set.Add(item))
{
   //item was added
}
else
{
  //item was not added
}

2. check to make sure it does not already exist. which is basically what set is doing
if(list.Contains(item)) return;
list.Add(item);
Reply all
Reply to author
Forward
0 new messages