NHibernate updating version when the entity was not changed

736 vues
Accéder directement au premier message non lu

steves

non lue,
21 juil. 2009, 15:43:3421/07/2009
à nhusers
Hi,

I have entity User with one-to-many relationship to
UserToUserCategories. When I load user from database, do not change it
and than flush the session, NHibernate will performs UPDATE of the
user and increment it's version. It seems to me as unwanted behaviour,
imagine that I load hundred of users and NHibernate would update them
all when flushing. Here is the code:

public abstract class EntityBase
{
public virtual Guid Id { get; set; }
public virtual int Version { get; set; }
}

public class User : EntityBase
{
public virtual IList<UserToUserCategory> UserToUserCategories
{ get; set; }
}

public class EntityBaseMap<T> : ClassMap<T> where T : EntityBase
{
public EntityBaseMap()
{
this.OptimisticLock.Version();
this.DynamicUpdate();
this.Id(t => t.Id);
this.Version(t => t.Version);
}
}

public class UserMap : EntityBaseMap<User>
{
public UserMap()
{
this.HasMany(u => u.UserToUserCategories)
.NotFound.Ignore()
.Cascade.All()
.LazyLoad()
.AsBag()
.WithTableName("UserToUserCategory");
}
}


session = SessionSource.CreateSession();
var user = (from u in session.Linq<User>() select u).FirstOrDefault();
session.Flush(); // here NHibernate does UPDATE statement of user's
version

Is this mapping incorrect? What am I missing?

Markus Zywitza

non lue,
22 juil. 2009, 10:20:1722/07/2009
à nhu...@googlegroups.com
Can you try with a backing field for Categories initialized with a List<..>-instance?
 
I had strange issues before with autoproperties on collections.
 
-Markus

2009/7/21 steves <steve....@gmail.com>

Fabio Maulo

non lue,
22 juil. 2009, 10:24:1122/07/2009
à nhu...@googlegroups.com
for autoproperties and access to field you can use
access="backfield"

2009/7/22 Markus Zywitza <markus....@gmail.com>



--
Fabio Maulo

Stefan Steinegger

non lue,
22 juil. 2009, 10:33:0622/07/2009
à nhusers
If NH does unnecessary updates, it is mostly due to implicit changes
within the entity. The properties must always return the exact value
that has been set by NH, if it is a collection, the entity must return
the same instance as set by NH, unless NH treats it as a change and
updates the database.

I never saw any issues with {get; set;} (which does not mean that
there aren't.)

Your code looks fine to me, but I don't know Fluent much. Is this
really the full code to reproduce the problem? You didn't leave
anything away because you thought it is irrelevant? For instance a
property getter or setter implementation?

On 22 Jul., 16:24, Fabio Maulo <fabioma...@gmail.com> wrote:
> for autoproperties and access to field you can useaccess="backfield"
>
> 2009/7/22 Markus Zywitza <markus.zywi...@gmail.com>
>
>
>
> > Can you try with a backing field for Categories initialized with a
> > List<..>-instance?
>
> > I had strange issues before with autoproperties on collections.
>
> > -Markus
>
> > 2009/7/21 steves <steve.side...@gmail.com>

steves

non lue,
22 juil. 2009, 15:09:5322/07/2009
à nhusers
Thank you guys, you got it.

The actuall code returns the collection as new ReadOnlyCollection
(this.userToUserCategory) that is created every time the getter is
called. So I added:

this.HasMany(u => u.UserToUserCategories).Access.AsCammelCaseField
()....

and it works perfect. Also lazy loading, which was working
incorrectly, now works fine. Now my question seems silly to me :(,
anyway thanks.

Fabio Maulo

non lue,
22 juil. 2009, 15:38:2722/07/2009
à nhu...@googlegroups.com
I strongly recommend the usage of the GhostBuster to prevent all this kind of surprise (it is only one test).



--
Fabio Maulo
Répondre à tous
Répondre à l'auteur
Transférer
0 nouveau message