-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 
Author Message
 Post subject: Bug or mapping issue?
PostPosted: Fri Sep 09, 2005 10:13 am 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
I've got a strange problem with some of my mappings...

Pretty much everything (both collections and individual entities) are set to lazy load. While still in the same session I'm getting this strange behaviour where a child of an entity will not evaluate to null but will also not appear to actually exist.

When examining one of these "non existent" entities using the VS.NET debugger the object type is showing as two empty braces '{}'.

Eg:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="Framework.Core.Entities" assembly="Framework.Core">

   <class name="User" table="Users" lazy="true" where="Deleted = 0">
   
      <id name="id" column="UserID" unsaved-value="0" access="field">
         <generator class="native" />
      </id>
      
      <version name="version" column ="Version" access="field"/>
      
      <property name="username" column="Username" length="50" access="field"/>
      <property name="password" column="Password" length="50" access="field"/>

      <many-to-one name="customer" column="CustomerID" class="Customer" access="field"/>
                   
  </class>
 
</hibernate-mapping>


with the other half:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="Framework.Core.Entities" assembly="Framework.Core">

   <class name="Customer" table="Customers" lazy="true" where="Deleted = 0">

      <id name="id" column="CustomerID" unsaved-value="0" access="field">
         <generator class="native" />
      </id>
      
      <version name="version" column="Version" access="field"/>

      
      <property name="name" column="Name" length="50" access="field"/>
      
      <bag name="users" lazy="true" access="field" where="Deleted = 0" inverse="true">
         <key column="CustomerID" />
         <one-to-many class="User" />
      </bag>
   
  </class>
 
</hibernate-mapping>


In this case I'm seeing the customer field of the User object as {} even though the correct data exists in the database for the object. I would have expected to see a proxy...

Removing the lazy attribute from the Customer object will cause the problem to go away, however I don't the whole object tree to load as we have quite a complex recursive relationship between many objects, so a lot of records would end up loaded.

I'm seeing this quite often - does anyone know why this might be happening?

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 10:47 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
I would say that "{}" you are seeing is a proxy, VS.NET has difficulties debugging dynamic proxies, for me, it often even crashes on them.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 11:17 am 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
Hmm...

If that's the case then I would have thought that touching on any of the properties of the proxy object would hit the DB and return the correct value. Sadly I'm getting null for the properties I try to hit. :(

I've set the logging level to DEBUG and touching the proxy (if that's what it is) isn't executing any statements causing any output.

Normally I DO get a proxy displayed in the debugger rather than '{}', so I'm not completely convinced that I'm not seeing something else here. ;)

Thanks for your quick response Sergey...do you have any other ideas?

Cheers,

Symon.

P.S. Ta for the RSS feed - makes a huge difference to my day!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 12:22 pm 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
Ok, and did you make the properties (and possibly methods) virtual so they can be intercepted and the proxy initialized?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 12:25 pm 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
Urrr...no. Didn't know I had to...

:)

I'll give it a go and report back.

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 12:33 pm 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
*sigh*

Nope...didn't work. Changing all properties and methods to virtual didn't help - I experience the exact same behavior.

Any other ideas? Or other info I can give you to try to assist with identifying the problem?

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 12:47 pm 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
OK, further interesting information:

When I load a Customer, which has a lazy bag of User objects, I can examine each user and it appears to have a child Customer object that I can navigate to.

When I load an IList of User object using a Query and examine it the child Customer for each returned entity appears as {}.

Is there something different in how a Query handles the retrieval?

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 09, 2005 6:25 pm 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
Further testing on this using reflection:

When a User is loaded using Get(), Find() or a Query the child Customer appears as {}. Using reflection and Debug.WriteLine statements to walk the properties of the Customer object the Id = 0 and all other properties are set to default value-type values or null. Mind you, if the same User is a member of a lazily loaded collection the Customer is fully populated.

Interestingly, using Load() actually returns an empty proxy as well and the Id of the returned proxy also remains 0 and isn't actually lazy loaded.

So it DOES look like it's a proxy, but it DOESN'T appear to be getting lazily loaded as it should be.

Hmmm.

Has anyone else seen similar behaviour? What I am doing wrong?

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 12, 2005 4:20 am 
Senior
Senior

Joined: Thu Jun 02, 2005 5:03 pm
Posts: 135
Location: Paris
*sigh*

Sergey, you were, of course, correct. I was seeing proxies and the reason they weren't working was that I'd missed settgin a property in a superclass to virtual.

I'm interested, though, in how to use an interface as a proxy rather than having to make all these properties virtual. I'd really prefer to have sealed classes.

When I try to use an interface as a proxy I'm getting an error when trying to build a SessionFactory:

Code:
NHibernate.Impl.SessionFactoryImpl: 2005-09-12 10:18:48,672 [5788] DEBUG NHibernate.Impl.SessionFactoryImpl [(null)] <(null)> - instantiating session factory with properties: {hibernate.dialect=NHibernate.Dialect.MsSql2000Dialect, hibernate.query.substitutions=true 1, false 0, hibernate.connection.connection_string=Data source=SROTTEM\VSDotNet;Initial Catalog=Papa.Framework;User Id=sa;Password=sqladmin, hibernate.connection.provider=NHibernate.Connection.DriverConnectionProvider, hibernate.connection.driver_class=NHibernate.Driver.SqlClientDriver}
Object reference not set to an instance of an object.
   at NHibernate.PropertyNotFoundException..ctor(Type type, String fieldName)
   at NHibernate.Property.FieldAccessor.GetField(Type type, String fieldName)
   at NHibernate.Property.FieldAccessor.GetField(Type type, String fieldName)
   at NHibernate.Property.FieldAccessor.GetGetter(Type theClass, String propertyName)
   at NHibernate.Mapping.Property.GetGetter(Type clazz)
   at NHibernate.Persister.AbstractEntityPersister..ctor(PersistentClass model, ISessionFactoryImplementor factory)
   at NHibernate.Persister.EntityPersister..ctor(PersistentClass model, ISessionFactoryImplementor factory)
   at NHibernate.Persister.PersisterFactory.CreateClassPersister(PersistentClass model, ISessionFactoryImplementor factory)
   at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, Settings settings)
   at NHibernate.Cfg.Configuration.BuildSessionFactory()
   at Papa.Framework.Core.Repository..ctor(String dbConnectionString) in C:\Documents and Settings\Symon\My Documents\Visual Studio Projects\Xpedite\PAPA\Papa.Framework.Core\Repository.cs:line 79
   at Papa.Framework.Core.Tests.FullPrivilegeTestCase.TestFixtureSetup() in C:\Documents and Settings\Symon\My Documents\Visual Studio Projects\Xpedite\PAPA\Papa.Framework.Tests\FullPrivilegeTestCase.cs:line 117


I've just added a proxy attribute to the class referring to the interface for the object.

Any thoughts?

Cheers,

Symon.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.