When using id generator class="assigned", why does extra select take place

364 views
Skip to first unread message

bstack

unread,
Feb 4, 2011, 9:24:01 AM2/4/11
to nhusers
Hi all,

I have a type with the following configuration:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-
access="field">
<class name="MyAssembly.SampleEntity, MyAssembly"
table="dbo.SampleEntity" lazy="false">
<id name="Id" column="Id">
<generator class="assigned" />
</id>
<property name="Prop1" />
<property name="Prop2" />
</class>
</hibernate-mapping>

We want to generate identifiers ourseleves. If we attempt to insert a
SampleEntity object into the database, why is NHibernate generating a
SELECT statement before executing an INSERT. Is there a way to stop
the SELECT being performed?

Many thanks.
Billy Stack

Jason Meckley

unread,
Feb 4, 2011, 11:21:37 AM2/4/11
to nhu...@googlegroups.com
NH needs to know if the entity already exists or not. the only way to determine this is to query the db. You can avoid the select by calling session.Update or session.Save depending on whether the entity already exists.

using Assigned means you want to take control of entity identification/persistence.

Billy Stack

unread,
Feb 5, 2011, 3:49:55 AM2/5/11
to nhu...@googlegroups.com
The entity will always be only ever inserted. 
The entity is immutable and will never be updated, we are essentially storing an event that has occurred (event sourcing)

In our repository we are currently using the following (standard) pattern:

using(var _session = _sessionFactory.OpenSession())
{
     _session.Save(myEntity);
}

You state that you can avoid select by calling session.Update or session.Save. Are we not already calling session.Save?

Cheers,
Billy Stack

On Fri, Feb 4, 2011 at 4:21 PM, Jason Meckley <jasonm...@gmail.com> wrote:
NH needs to know if the entity already exists or not. the only way to determine this is to query the db. You can avoid the select by calling session.Update or session.Save depending on whether the entity already exists.

using Assigned means you want to take control of entity identification/persistence.

--
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,
Feb 5, 2011, 10:10:55 AM2/5/11
to nhu...@googlegroups.com
this worked in my situation, but the entities I was saving where children of a parent entity that was resolved from session. so the context is slightly different. In your situation it sounds like the entity with the assigned id is the root.

You know it's an insert only model, but NH doesn't know that, so it needs to check if it exists. There may be a mapping/configuration setting that prevents load before save, or prevents updates, but I not 100% sure about that.

If that doesn't work (or exist) I would change the POID strategy to allow NH/DB to handle it. If the assigned ID has business meaning, then map this as an immutable attribute of the entity.

Another option is to drop the use of NH altogether. I haven't used event sourcing myself, but what little I understand it suppose to simplify persistence concerns. If that's the case then NH or an RDBMS wouldn't be required.

Billy Stack

unread,
Feb 6, 2011, 4:29:50 AM2/6/11
to nhu...@googlegroups.com
The Id for the entity we were generating was a comb guid. Rather than the code setting this we just changed the id generator to "guid.comb". No select is performed by NHibernate by default when we perform a save.
 
Thanks for the help
Billy Stack

Richard Brown (gmail)

unread,
Feb 6, 2011, 5:17:27 AM2/6/11
to nhu...@googlegroups.com
Hi Billy,
 
The warning occurs when you call SaveOrUpdate() on an entity with an 'assigned' identifier.
 
When NH doesn't control the IDs, it can't tell if that instance should be saved (it's new), or updated (it already exists in the DB), so it warns you to let you know it's hitting the DB (twice) when you might not have expected it to.
 
The fix that caused this behaviour:  http://216.121.112.228/browse/NH-1914
 
Regards,
    Richard
To unsubscribe from this group, send email to mailto:nhusers%2Bunsu...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.

Billy Stack

unread,
Feb 6, 2011, 8:51:43 AM2/6/11
to nhu...@googlegroups.com
Hi Richard,
 
Thanks for the information.
I am now using guid.comb as the POID strategy. Our database is just simply storing events.
This generates just an insert only when using a simple entity - which is what we want.
 
However I cant get it to work for complex types e.g an order with many order items.
Is the following scenario possible?

Parent entity where POID = guid.comb
Child entity where POID = guid.comb
Note: One Parent has many children.
 
When I attempt to do a save I get an exception:
 
NHibernate: INSERT INTO MoreComplexMapping_Order (CustomerId, Description, Id) VALUES (@p0, @p1, @p2);@p0 = 1, @p1 = 'My new order', @p2 = dbe893b4-fa1c-4779-8f48-9e8200e36eb1
NHibernate: UPDATE MoreComplexMapping_OrderItem SET OrderId = @p0, Description = @p1 WHERE Id = @p2;@p0 = NULL, @p1 = 'desc 1', @p2 = 946475f6-f670-4a5b-945a-e033836ff002
13:48:03,560 ERROR [   7] AbstractFlushingEventListener [(null)]- Could not synchronize database state with session
 
It seems to attempt to do an update when I want it to do an insert.
 
Regards,
Billy Stack

Richard Brown (gmail)

unread,
Feb 6, 2011, 10:26:03 AM2/6/11
to nhu...@googlegroups.com
That should be fairly straightforward to do.  I’d need to see your mappings and code to see what’s wrong in this case, but I suspect it’ll be that you want to use inverse=”true” on the collection (if you’re setting the back-pointer from the child to the parent yourself).

Billy Stack

unread,
Feb 6, 2011, 4:57:49 PM2/6/11
to nhu...@googlegroups.com
Found out the issue.
I was manually setting the Id of the OrderItem entity when the POID was guid.comb. Changed the code to no longer set the Id and all worked as expected.
 
Still needed inverse="true" in child collection definition as otherwise UPDATE statements (in the OrderItem table) were being generated.
 
Thanks for the help. NHibernate can work with event sourcing!
 
Billy Stack

bstack

unread,
Feb 7, 2011, 7:01:48 AM2/7/11
to nhusers
Does anyone know if there is any way to stop NHibernate performing
selects when using POID = "assigned"?

On Feb 6, 9:57 pm, Billy Stack <bs.st...@gmail.com> wrote:
> Found out the issue.
> I was manually setting the Id of the OrderItem entity when the POID was
> guid.comb. Changed the code to no longer set the Id and all worked as
> expected.
>
> Still needed inverse="true" in child collection definition as otherwise
> UPDATE statements (in the OrderItem table) were being generated.
>
> Thanks for the help. NHibernate can work with event sourcing!
>
> Billy Stack
>
> On Sun, Feb 6, 2011 at 3:26 PM, Richard Brown (gmail) <
>
>
>
> fluke...@googlemail.com> wrote:
> >   That should be fairly straightforward to do.  I’d need to see your
> > mappings and code to see what’s wrong in this case, but I suspect it’ll be
> > that you want to use inverse=”true” on the collection (if you’re setting the
> > back-pointer from the child to the parent yourself).
>
> >   *From:* Billy Stack <bs.st...@gmail.com>
> > *Sent:* Sunday, February 06, 2011 1:51 PM
> > *To:* nhu...@googlegroups.com
> > *Subject:* Re: [nhusers] Re: [NH users] Re: When using id generator
> >>http://groups.google.com/group/nhibernate-development/browse_thread/t...
>
> >> Regards,
> >>     Richard
>
> >>   *From:* Billy Stack <bs.st...@gmail.com>
> >> *Sent:* Sunday, February 06, 2011 9:29 AM
> >> *To:* nhu...@googlegroups.com
> >> *Subject:* Re: [nhusers] Re: When using id generator class="assigned",
> >> why does extra select take place
> >>    The Id for the entity we were generating was a comb guid. Rather than
> >> the code setting this we just changed the id generator to "guid.comb". No
> >> select is performed by NHibernate by default when we perform a save.
>
> >> Thanks for the help
> >> Billy Stack
>
> >>   On Sat, Feb 5, 2011 at 3:10 PM, Jason Meckley <jasonmeck...@gmail.com>wrote:
>
> >>>  this worked in my situation, but the entities I was saving where
> >>> children of a parent entity that was resolved from session. so the context
> >>> is slightly different. In your situation it sounds like the entity with the
> >>> assigned id is the root.
>
> >>> You know it's an insert only model, but NH doesn't know that, so it needs
> >>> to check if it exists. There may be a mapping/configuration setting that
> >>> prevents load before save, or prevents updates, but I not 100% sure about
> >>> that.
>
> >>> If that doesn't work (or exist) I would change the POID strategy to allow
> >>> NH/DB to handle it. If the assigned ID has business meaning, then map this
> >>> as an immutable attribute of the entity.
>
> >>> Another option is to drop the use of NH altogether. I haven't used event
> >>> sourcing myself, but what little I understand it suppose to simplify
> >>> persistence concerns. If that's the case then NH or an RDBMS wouldn't be
> >>> required.
>
> >>> --
> >>> 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
> >>> mailto:nhusers%2Bunsu...@googlegroups.com<nhusers%2Bunsubscribe@googleg­roups.com>.
>
> >>> For more options, visit this group at
> >>>http://groups.google.com/group/nhusers?hl=en.
>
> >> --
> >> 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
> >> mailto:nhusers%2Bunsu...@googlegroups.com<nhusers%2Bunsubscribe@googleg­roups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/nhusers?hl=en.
> >>  --
> >> 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
> >> mailto:nhusers%2Bunsu...@googlegroups.com<nhusers%2Bunsubscribe@googleg­roups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/nhusers?hl=en.
>
> > --
> > 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.
>
> > --
> > 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.- Hide quoted text -
>
> - Show quoted text -
Reply all
Reply to author
Forward
0 new messages