-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Using Native SQL Query deletes the second level cache
PostPosted: Thu Jul 28, 2011 10:49 am 
Newbie

Joined: Thu Jul 28, 2011 10:06 am
Posts: 1
Hi,

In our project, I observed that when we use Native SQL query for any DML statement, the entities in second level cache were evicted. Could someone please provide some insight into avoiding this scenario without any performance impact?

From my analysis:

When I used a profiling tool to identify the cause, I observed that calls originating from the executeUpdate on a query implementation of native SQL resulted in eviction of entities from second level cache.

From Hibernate code walk through,
1. When creating a Native SQL using session instance, by default queryspaces is set to null
2. When invoking executeUpdate on the query, it deletes all the entities from cache if the queryspaces is null.
3. I also understand that using addSynchronizedEntityClass method on the query class should add queryspaces thus avoiding eviction from second level cache. But I am sceptical of using this as it would be doing additional conditional check in this case as evident from the code below code from BulkOperationCleanupAction class


Code:
public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces)
  {
    this.session = session;

    Set tmpSpaces = new HashSet(querySpaces);
    SessionFactoryImplementor factory = session.getFactory();
    Iterator iterator = factory.getAllClassMetadata().entrySet().iterator();
    while (iterator.hasNext()) {
      Map.Entry entry = (Map.Entry)iterator.next();
      String entityName = (String)entry.getKey();
      EntityPersister persister = factory.getEntityPersister(entityName);
      Serializable[] entitySpaces = persister.getQuerySpaces();

      if (affectedEntity(querySpaces, entitySpaces)) {
        if (persister.hasCache()) {
          this.affectedEntityNames.add(persister.getEntityName());
        }
        Set roles = session.getFactory().getCollectionRolesByEntityParticipant(persister.getEntityName());
        if (roles != null) {
          this.affectedCollectionRoles.addAll(roles);
        }
        for (int y = 0; y < entitySpaces.length; y++) {
          tmpSpaces.add(entitySpaces[y]);
        }
      }
    }

    this.spaces = ((Serializable[])(Serializable[])tmpSpaces.toArray(new Serializable[tmpSpaces.size()]));
  }

  private boolean affectedEntity(Set querySpaces, Serializable[] entitySpaces)
  {
    if ((querySpaces == null) || (querySpaces.isEmpty())) {
      return true;
    }

    for (int i = 0; i < entitySpaces.length; i++) {
      if (querySpaces.contains(entitySpaces[i])) {
        return true;
      }
    }
    return false;
  }


Correct me if my understanding is wrong with respect to Hibernate code flow. It would be great if someone can advice on how to use Native SQL without evicting the objects from second level cache. Meanwhile, we are trying to use HQL or update on attached entities to avoid this behavior.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.