[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-3910) custom dirty flag tracking

Steve Ebersole (JIRA) noreply at atlassian.com
Wed Jan 25 11:24:13 EST 2012


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

Steve Ebersole commented on HHH-3910:
-------------------------------------

{quote}
Taking a peek at the changes, the resetDirty call isn't buried in the core? i.e. we'll have the flexibility to call it where it makes the most sense?
{quote}

Not really sure what you are asking here.  {{resetDirty}} is called after changes are written to the db.  You have to keep in mind that with this approach your code is now the keeper of this dirty flag.  Hibernate can't reset it because you control it.  So you can reset it whenever you see fit.  This is just a hook for Hibernate to tell you that its probably a good time to reset it because those changes have been written to the db.

{quote}
I'm not sure of the case where I'd have 2 pieces of logic called for isDirty and canDirtyCheck but I need to think through how I'll tie into it. I think we'll find in our cases quite a bit of improvement if we can bypass the check on our large entities.
{quote}
Well I think you have to remember that this is plugged in at the {{SessionFactory}} level.  You may not be controlling a dirty flag for each and every entity.  Hence the {{canDirtyCheck}}.

Right now, {{isDirty}} only has a perf benefit if it returns false which will circumvent the "dirty checking".  Something to keep in mind that "dirty checking" also encompasses figuring out which attributes changed.  If {{isDirty}} returns true, we still need to do that work in order to determine which attributes changed.

Something extra I have contemplated here (still not sure) is to expand this {{CustomEntityDirtinessStrategy}} concept a little to also allow it to report which attributes are changed, something akin to {{org.hibernate.Interceptor#findDirty}}.

> custom dirty flag tracking
> --------------------------
>
>                 Key: HHH-3910
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3910
>             Project: Hibernate ORM
>          Issue Type: Improvement
>          Components: core
>    Affects Versions: 3.3.1
>            Reporter: Ovidio Mallo
>            Assignee: Steve Ebersole
>              Labels: performance
>             Fix For: 4.1.0
>
>         Attachments: DirtyCheckFailedAttempt.patch
>
>          Time Spent: 4h 26m
>
> 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.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list