[hibernate-dev] Bytecode enhancement

Emmanuel Bernard emmanuel at hibernate.org
Tue Oct 9 10:57:12 EDT 2012


On Thu 2012-10-04 10:00, Steve Ebersole wrote:
> See https://hibernate.onjira.com/browse/HHH-7667
> 
> I want to investigate expanding Hibernate's support for bytecode 
> enhancement.  I can see 3 main fronts to this:
> 
> 1) offloading map lookups from the PersistenceContext .  Currently we 
> keep state associated with each entity in a map (a special type of map 
> called IdentityMap) on the PersistenceContext, keyed by the entity. 
> Profiling consistently shows these maps as a hot-spot.  The main thing 
> we keep in the PersistenceContext in regards to the entity is called an 
> EntityEntry, which is kept in an IdentityMap<Object,EntityEntry> (again, 
> the entity is the key).  So the thought here is to invert this from 
> `map.get( entity )` to something like `( (Enhanced) entity 
> ).getEntityEntry()`

I was discussing this with Sanne. One "workaround" to the heavy
IdentityMap price is to keep a contextual cache. I am pretty sure these
IndeitityMap lookups are done over and over for a given operation.

We might be able to:

- pass along the EntityEntry instead of relying on the lookup several
  times
- use a cache of lookups for either the most recent or for the
  contextual operation.

The cache would be array based and thus not involve hashcode or lookup.

for ( int index = 0 ; index < cache.length ; index++ ) {
  if ( searchedO == cache[index] ) {
    entityEntry = entityEntryCache[index];
  }
}
if ( entityEntry == null ) {
  identityMap.get(searchedO);
  //add to cache
}

Alternatively, I don't remember what is costly, the actual lookup or the
computation of the identity hashcode.
If that's the former, we can take the bet and use the entity hashcode
instead but still use == instead of equals. The risk is more collisions
or in case of a rogue implementation of hashCode not finding the entity.

These options seems more lightweight than relying on bytecode
enhancement to keep a placeholder.

> 
> 2) More performant dirty-checking.  This already exists, to an extent, 
> in the current Hibernate bytecode.  The idea being that we could use 
> "interception" within the enhanced entity to know when it becomes dirty. 
>   Well, almost.  What is missing is "deep checking of mutable state 
> fields".  For example, an entity attribute of type Date that is 
> "changed" via entity.getSomeDate().setTime( ... ).  The entity needs to 
> be found dirty here, because its "someDate" attribute value has changed, 
> but interception will not catch this.  And I think this should be 
> configurable (whether the user wants us to perform "deep mutable state 
> checking").  We have all the pieces in place to handle this already 
> through Type.isMutable() as Hibernate already does a great job of 
> finding dirty fields in the most flexible manner.  We just need to 
> determine how to best wire that up into enhancement.

Either check the deep state via the type system or consider an element
as dirty when it is read.

> 3) Alternative means for lazy loading of entity state, meaning an 
> alternative to using proxies for the same purpose.  This is different, 
> too, from the current enhancement capability of lazy loading of property 
> state.  Lazy property loading is meant to delay loading of certain 
> field(s) until they are accessed.
> 

You lost me on that one, I'm not sure what you mean here.

Emmanuel


More information about the hibernate-dev mailing list