[hibernate-dev] RE: EntityPersister.initializeLazyProperty: ask for one, initialize all?

Nikita Tovstoles nikita at doppelganger.com
Tue May 26 13:18:03 EDT 2009


Thanks for getting back to me, Steve. Yep, I realized that subsequently and submitted a patch. Please see my latter e-mails with further details.

-nikita

-----Original Message-----
From: Steve Ebersole [mailto:steven.ebersole at gmail.com] On Behalf Of Steve Ebersole
Sent: Tuesday, May 26, 2009 10:17 AM
To: Nikita Tovstoles
Cc: hibernate-dev at lists.jboss.org
Subject: RE: [hibernate-dev] RE: EntityPersister.initializeLazyProperty: ask for one, initialize all?

Hey Nikita

Bad timing as the US had a long weekend, so most of us were not around.

I'll take a look at this tomorrow and get back to you.

WRT your specific question... AFAIR, the reason cloning would be needed
was that you would need to remove the property names as they are
initialized.  The set of lazy property names are defined per tuplizer
which is scoped to the persister which is scoped to the sessionfactory.
So, as it stands right now, removing a property name from that set once
a lazy property is initialized would remove it "everywhere".  Cloning
would give each FieldInterceptor (associated to each bytecode enhanced
entity) its own set with which to work.

In pseudo code think of it as:

Set unitializedPropertyNames = ...;  // shared instance as of now

Entity yourEnhancedEntity = new Entity();
yourEnhancedEntity.injectInterceptor( 
    new Interceptor( unitializedPropertyNames, ... )
);

Entity anotherEnhancedEntityInst = new Entity();
anotherEnhancedEntityInst.injectInterceptor( 
    new Interceptor( unitializedPropertyNames, ... )
);

Notice both entity instances share the same 'unitializedPropertyNames'
set reference...

On Sun, 2009-05-24 at 19:51 -0700, Nikita Tovstoles wrote:
> Submitted a patch to Hibernate Core 3.3.1.GA that fixes the issue for multiple lazy one-to-one's on a shared PK. I think the only thing(s) left to do to enable un-batched lazy property initialization for cases other than one-to-one on a shared PK are:
> - generate appropriate sql lazySelectString given property being requested (in AbstractEntityPersister.initializeLazyPropertiesFromDatastore)
> - possibly alter CacheEntry to enumerate uninitialized properties (rather than simply store a boolean value)
> 
> I've tested my changes but, of course, would appreciate feedback from someone who knows Hibernate internals better than I do. My patch and further comments can be found here:
> http://opensource.atlassian.com/projects/hibernate/browse/HHH-2309?focusedCommentId=33239#action_33239
> 
> -nikita
> 
> 
> -----Original Message-----
> From: hibernate-dev-bounces at lists.jboss.org [mailto:hibernate-dev-bounces at lists.jboss.org] On Behalf Of Nikita Tovstoles
> Sent: Friday, May 22, 2009 8:57 PM
> To: hibernate-dev at lists.jboss.org
> Subject: [hibernate-dev] RE: EntityPersister.initializeLazyProperty: ask for one, initialize all?
> 
> Naturally, things are a bit more involved:
> -replaced AbstractFieldInterceptor.initializing with a Set tracking that state on a per-fieldName basis.
> 
> That wasn't enough - TestLazyExecutable is failing - returning a null value - it almost seems as though the same FilterInterceptor instance is reused by multiple sessions after my awesome coding.
> 
> I assumed that at most (or exactly?) one AbstractFieldInterceptor impl instance is created per entity instance per Session and that no fieldInterceptor is used by multiple sessions. 
> 
> The interceptor seems to be injected with lazyProps only in PojoEntityTuplizer.afterInitialize() where the following comment resides:
> 
> //TODO: if we support multiple fetch groups, we would need
> //      to clone the set of lazy properties!
> FieldInterceptionHelper.injectFieldInterceptor( entity, getEntityName(), lazyProps, session );
> 
> 
> Why is cloning needed? Is it because my assumption about the lifespan of one is incorrect? Is a new FieldInterceptor created every time a different lazy property is accessed for the first time on the same entity?
> 
> Thanks
> 
> -nikita
> 
> 
> 
> 
> -----Original Message-----
> 
> Our app fails to scale sufficiently and I'd traced our problems to eager loading of all OneToOne relations when any single one is accessed. I would like to fix that but wanted to get feedback first. I'm referring to Hibernate Core 3.3.1.GA below:
> 
> Currently in AbstractFieldInterceptor.intercept():
> "uninitializedFields = null; //let's assume that there is only one lazy fetch group, for now!"
> 
> proposed fix: 
> -after 'result' is returned call uninitializedFields.remove(fieldname). Question: should this only be done if result != null?
> 
> And then AbstractEntityPersister.initializeLazyProperties() calls methods that initialize *all* properties even though a specific fieldname is supplied:
> * initializeLazyPropertiesFromDatastore or
> * initializeLazyPropertiesFromCache
> 
> Proposed fix:
> -In both cases, determine appropriate 'j' value by searching lazyPropertyNames for 'fieldName'
> -only call nullSafeGet, and initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) once.
> 
> 
> What do folks think?
> 
> Thanks,
> -nikita
> 
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev
-- 
Steve Ebersole <steve at hibernate.org>
Hibernate.org





More information about the hibernate-dev mailing list