[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-7206) NaturalIdLoadAccess: NaturalId synchronization with no need to flush at all

Guenther Demetz (JIRA) noreply at atlassian.com
Thu Mar 29 09:54:50 EDT 2012


    [ https://hibernate.onjira.com/browse/HHH-7206?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=46117#comment-46117 ] 

Guenther Demetz commented on HHH-7206:
--------------------------------------

Here following a concrete example in which these enhancement show the impact on performance.

Assume we have a entity class representing the yearly final stocks of a magazine.

{code}
@Entity
class FinalStock {
  @Id 
  long id;

  @NaturalId(mutable=true)
  String articleNumber;

  @NaturalId(mutable=true)
  int year;

  @OneToMany(cascade=All)
  Set<Inventory> inventories;
}
{code}

Immagine that we want compare all final stocks between the years 2011 and 2010,
in order to avoid multiple database hits, we fetch all interested entities into persistent context with a single query,
that's reasonable.

{code}
//session.setFlushMode(Auto) leaving it to the default flush mode
List<FinalStock> list = session.createQuery("from FinalStock where year in (2011,2010)").list(); // loading 1.000 FinalStock objs
for (FinalStock stock : list) {
  String correspondging_article_other_year = calculate(stock); //algorythm which cannot replaced by a sofisticated outer join query
  FinalStock stockOtherYear = session.byNaturalId(FinalStock.class).using("articleNumber",correspondging_article_other_year).
                              using("year",getOtherYear(stock.year)).load();

  if (stockOtherYear != null) { // true for 90% or cases
      //do some work here causing dirty FinalStock objects and dirty collections
      Inventory inv = new Inventory(....);
      stock.add(inv); 
  }
}
{code}

As we have all concerning entities already loaded in context, 
and as there's an excpectance around 90% to retrieve the corresponding stock,
we should expect the NaturalId lookups performing very fast.

In truth without the first enhancement above, hibernate would spend most of it's time in 1000 total unnecessary and expensive dirty check/session flushes.
With the first enhancement implemented, hibernate still would spend substantial time in synchronizing 1000 times (for each naturalIdLoadAccess) the 1000 FinalStocks which are in context.
With the second enhancement implemented too(using setAutoSynchronization set to false), the whole thing begins to work in reasonable way.
The last wormwood to eliminate are the queries (database-hits) which are performed in those 10% of the cases, 
where the corresponding NaturalId get not resolved from cache. 
Since in our concrete case we have already loaded all interested objects in context, those queris are pure overhead.

So finally it would be fine to have a further method on NaturalIdLoadAccess allowing do prevent loads from datasource.

This 3 enhancements put together in my opinion would open new horizons in hibernate,
allowing to do fast in-memory operations which previously were only possible with huge user-code.

Please give us your feedback ...

> NaturalIdLoadAccess: NaturalId synchronization with no need to flush at all
> ---------------------------------------------------------------------------
>
>                 Key: HHH-7206
>                 URL: https://hibernate.onjira.com/browse/HHH-7206
>             Project: Hibernate ORM
>          Issue Type: Improvement
>          Components: core
>    Affects Versions: 4.1.1
>         Environment: Hibernate4, database-independent
>            Reporter: Guenther Demetz
>              Labels: flush, naturalId
>
> With few code changes I think it is possible to make NaturalIdLoadAccess work with no need to rely on flush at all,
> please see following comments.

--
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