-->
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.  [ 2 posts ] 
Author Message
 Post subject: one-to-one
PostPosted: Fri Oct 15, 2010 10:35 am 
Newbie

Joined: Fri Oct 15, 2010 10:20 am
Posts: 1
Any help with this is appreciated...

I looked on the forums and found several questions regarding a one-to-one mapping and lazy loading. I have read the documentation about setting lazy="no-proxy" and adding constraint=true. After researching this and trying different mappings the one-to-one is still fetching the association eagerly.

When User is retrieved Hibernate also selects userDetail which is not the expected outcome. I added constrained=true on both sides (I am not sure if this is necessary Hibernate is probably smart enough to determine that both sides cannot be null). The documentation states that build time instrumentation is required for no-proxy and from reading other postings CGLIB is in the classpath.

Using Hibernate 3.2.2

Code:
<class name="core.User" ... >
<one-to-one
       name="userDetail"
   class="core.userDetail"
   cascade="all"
   constrained="true"
   lazy="no-proxy"      
   />
</class>

<class name="core.UserDetail" ... >
<one-to-one
        name="user"
   class="core.User"
        constrained="true"
/>
</class>


I looked at the code and noticed the following ...

Code:
boolean lazyAvailable = persistentClass.hasPojoRepresentation() &&
FieldInterceptionHelper.isInstrumented( persistentClass.getMappedClass() );


is executed in the EntityMetamodel constructor and FieldInterceptionHlper.isIntrumented(...) always returns false. I checked the one-to-one property and lazy is true for Property.isLazy ...

Code:
if ( value instanceof ToOne ) {
   // both many-to-one and one-to-one are represented as a
   // Property.  EntityPersister is relying on this value to
        // determine "lazy fetch groups" in terms of field-level
        // interception.  So we need to make sure that we return
   // true here for the case of many-to-one and one-to-one
   // with lazy="no-proxy"
   //
   // * impl note - lazy="no-proxy" currently forces both
   // lazy and unwrap to be set to true.  The other case we
   // are extremely interested in here is that of lazy="proxy"
   // where lazy is set to true, but unwrap is set to false.
   // thus we use both here under the assumption that this
   // return is really only ever used during persister
   // construction to determine the lazy property/field fetch
   // groupings.  If that assertion changes then this check
   // needs to change as well.  Partially, this is an issue with
   // the overloading of the term "lazy" here...
   ToOne toOneValue = ( ToOne ) value;
   return toOneValue.isLazy() && toOneValue.isUnwrapProxy();
   }
return lazy;



According to the documentation one-to-one only needs build time instrumentation for lazy loading and for this all you need is to place CGLIB jars in the classpath. If this field is always false then ...

Code:
boolean lazy = prop.isLazy() && lazyAvailable;
if ( lazy ) hasLazy = true;
propertyLaziness[i] = lazy;


the variable propertyLaziness[i] is always false. This array is later used in determining the hydrated state within the AbstractEntityPersister class ...

Code:
            
else if ( allProperties || !laziness[i] ) {
   //decide which ResultSet to get the property value from:
   final boolean propertyIsDeferred = hasDeferred &&
      rootPersister.isSubclassPropertyDeferred( propNames[i], propSubclassNames[i] );
   if ( propertyIsDeferred && sequentialSelectEmpty ) {
      values[i] = null;
   }
        else {
       final ResultSet propertyResultSet = propertyIsDeferred ? sequentialResultSet : rs;
       final String[] cols = propertyIsDeferred ? propertyColumnAliases[i] : suffixedPropertyColumns[i];
       values[i] = types[i].hydrate( propertyResultSet, cols, session, object );
   }
}
else {
   values[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
}


notice if laziness is false that execution enters the else-if block skipping the else which sets values[i] to LazyPropertyInitializer.UNFETCHED_PROPERTY. The values[] is used later when hydrating the entity in the TwoPhaseLoad class ...

first the code retrieves the hydratedState
Code:
Object[] hydratedState = entityEntry.getLoadedState();


then there is a loop on the properties to resolves non-lazy properties...

Code:
      
Type[] types = persister.getPropertyTypes();
for ( int i = 0; i < hydratedState.length; i++ ) {
   final Object value = hydratedState[i];
   if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
      hydratedState[i] = types[i].resolve( value, session, entity );
   }
}


the if condition says it all the fact that the value will never be LazyPropertyInitializer.UNFETCHED_PROPERTY means the property will be resolved and essentially loaded ... eagerly.


Top
 Profile  
 
 Post subject: Re: one-to-one
PostPosted: Mon Jan 24, 2011 4:23 am 
Newbie

Joined: Mon Jan 24, 2011 3:57 am
Posts: 1
Hi

Did you find the reason why FieldInterceptionHelper.isInstrumented always returns false ?

I have the same problem...


Regards


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.