[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3910) Add support for custom dirty checking during flush

Ovidio Mallo (JIRA) noreply at atlassian.com
Sat May 16 05:22:14 EDT 2009


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-3910?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=33186#action_33186 ] 

Ovidio Mallo commented on HHH-3910:
-----------------------------------

Does the problem of having wrong values in EntityEntry#getLoadedState() already occur if using bytecode instrumentation for dirty checking? Do you maybe have a testcase where I could reproduce this?

BTW, I'm not sure whether the current check in the patch as of whether a dirty check is required or not is correct. Right now, it reads as follows:

return isMutableInstance && (
        getPersister().hasMutableProperties() && getPersister().isDirtyCheckRequired(entity)||
        !FieldInterceptionHelper.isInstrumented( entity ) ||
        FieldInterceptionHelper.extractFieldInterceptor( entity).isDirty()
    );

In particular, I'm not sure about the following two points:
* If getPersister().hasMutableProperties() == false and getPersister().isDirtyCheckRequired(entity) == true, dirty checking may be skipped even though it should probably be performed.
* If a mutable entity is not instrumented, the expression seems to always return true, thus leading to a dirty check even if getPersister().isDirtyCheckRequired(entity) == false.


I would rather have expected something like the following (I've split things up to keep them simpler):

if (!isMutableInstance) {
    return false;
}

if (getPersister().hasMutableProperties()) {
    return true;
}

// Do custom dirty checking before doing dirty checking through bytecode instrumentation.
if (!getPersister().isDirtyCheckRequired(entity)) {
    return false;
}

return !FieldInterceptionHelper.isInstrumented( entity ) || FieldInterceptionHelper.extractFieldInterceptor( entity).isDirty();

> Add support for custom dirty checking during flush
> --------------------------------------------------
>
>                 Key: HHH-3910
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3910
>             Project: Hibernate Core
>          Issue Type: Improvement
>          Components: core
>    Affects Versions: 3.3.1
>            Reporter: Ovidio Mallo
>         Attachments: DirtyCheckFailedAttempt.patch
>
>
> Currently, Hibernate supports a special dirty checking on instrumented entities
> in order to improve the flush performance. IMO, this optimization can often be
> rather significant. However, the drawback is that you have to use bytecode
> instrumentation in order to take advantage of this performance improvement which
> might not be an option in some projects.
> Therefore, I wanted to propose to extend the current dirty checking during flush
> in such a way that the dirtyness information can also be directly provided by
> clients. Thereby, I could think of two possible approaches to do this:
> 1. Introduce an interface which client entities might implement in case they
>    have some notion of dirtyness. The interface could look something like:
>      public interface DirtyAwareEntity {
>        boolean getMightBeDirty();
>        void setMightBeDirty(boolean mightBeDirty);
>      }
>    Using such an interface, Hibernate could easily check whether an entity might
>    be dirty during flush and it could also reset the dirty flag after flush just
>    as is currently done for instrumented classes. So this approach would probably
>    be rather easy to implement and very convenient for clients since they would
>    only have to implement that interface on the appropriate entities and set the
>    dirty flag when the entity is actually modified.
> 2. Add some hooks on event listeners and/or on the Interceptor for querying whether
>    an entity is dirty and for resetting the dirty flag. E.g. one could add the
>    following hook method to the DefaultFlushEntityEventListener class:
>      protected boolean requiresDirtyCheck(FlushEntityEvent event);
>    By default, this method would call EntityEntry#requiresDirtyCheck(Object entity)
>    as is done right now.
>    Resetting the dirty flag could maybe be done in Interceptor#postFlush() or some
>    dedicated method could be provided.
> BTW, I know that currently there already is the Interceptor#findDirty() method which
> already allows for some custom dirty checking but the problem from a performance
> point of view is that this method requires the entity's property values as parameter
> which are retrieved in DefaultFlushEntityEventListener#getValues() which is the most
> expensive method during flush. This drawback of the findDirty() method has often been
> noticed in comments on the news groups.
> I personally think it would be nice if something could be done to improve the
> performance of flushing in Hibernate since from what I read on the news groups and
> the like, flushing still seems to often lead to performance problems in practice,
> especially in larger projects where it is often not easy to avoid flushes or to
> keep the numer of entities in the session cache small. In fact, we are having quite
> some trouble with that in our project and having some custom dirty checking like the
> one I'm proposing here would greatly help in our project and in other projects as
> well, I guess.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list