-->
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.  [ 4 posts ] 
Author Message
 Post subject: Evict question: doesn't always work?
PostPosted: Fri Nov 20, 2009 3:39 pm 
Newbie

Joined: Thu Nov 19, 2009 10:32 pm
Posts: 1
I've got a web application using hibernate3.jar, and it works fine most of the time. I have objects in the application that I fetch, create, update, etc., via Hibernate, some of which are stored in the (web app) session for future use. We use lazy loading, so occasionally I will come across an object that had been loaded by an earlier Hib Session, in which case I lock it to the current Session. I can't always predict when I will run into a situation where I will need to lock, so I use the following algorithm in some cases:
Code:
try {
   log.debug("Processing " + foo.getBars().size() + " Bars");
   setBar = foo.getBars();
}
catch (Exception e) {
   session.lock(foo, LockMode.NONE);
}

In this case, foo's set of Bar objects is lazily loaded. Sometimes the set will be loaded without incident, and other times there will be a exception of the type
Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: foo.bars, no session or session was closed

in which case the foo is locked and we go on our merry way.

Well, recently I came across a situation where the lock resulted in the following:
Code:
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [Foo#1006561]

so I inserted a second try/catch:
Code:
try {
   log.debug("Processing " + foo.getBars().size() + " Bars");
   setBar = foo.getBars();
}
catch (Exception e) {
   try {
      session.lock(foo, LockMode.NONE);
   } catch (Exception e1) {
      session.evict(foo);
      session.flush();
      session.lock(foo, LockMode.NONE);
   }
}

but this fails too with the same NonUniqueObjectException! So I had to resort to loading the set separately:
Code:
try {
   log.debug("Processing " + foo.getBars().size() + " Bars");
   setBar = foo.getBars();
}
catch (Exception e) {
   try {
      session.lock(foo, LockMode.NONE);
   } catch (Exception e1) {
      try {
         session.evict(foo);
         session.flush();
         session.lock(foo, LockMode.NONE);
      } catch (Exception e2) {
         // What the - ?  How is this possible?
         setBar = session.CreateCriteria(Bar.class)
            .add(Restrictions.eq("foo", foo))
            .list();
      }
   }
}


So my question is, if I evict the object, how can I then be told that I have a non-unique object?

Thanks
~Paul T.


Top
 Profile  
 
 Post subject: Re: Evict question: doesn't always work?
PostPosted: Wed Mar 31, 2010 1:02 am 
Newbie

Joined: Thu Mar 15, 2007 10:03 pm
Posts: 6
Hi,

Same problem here. Weird behavior.

Object reattachment (to the hibernate session) has been a frustrating problem for me (using Open Session in View pattern and Lazy loading).

Anything new about the evict() that doesn't actually evict?

Thanks!


Top
 Profile  
 
 Post subject: Re: Evict question: doesn't always work?
PostPosted: Wed Mar 31, 2010 2:22 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
I don't think there is something strange about this. If the call to session.lock(foo) doesn't succeed because there is another object with the same id, then the call session.evict(foo) will not succeed either. foo is still not part of the session and evict() expects an object that is already in the session.

Instead of trying to lock and evict, use session.get():

Code:
foo = session.get(Foo.class, foo.getId());
setBar = foo.getBars();


Top
 Profile  
 
 Post subject: Re: Evict question: doesn't always work?
PostPosted: Wed Mar 31, 2010 8:20 am 
Newbie

Joined: Thu Mar 15, 2007 10:03 pm
Posts: 6
nordborg wrote:
I don't think there is something strange about this. If the call to session.lock(foo) doesn't succeed because there is another object with the same id, then the call session.evict(foo) will not succeed either. foo is still not part of the session and evict() expects an object that is already in the session.

Instead of trying to lock and evict, use session.get():

Code:
foo = session.get(Foo.class, foo.getId());
setBar = foo.getBars();


Hi!

The code was :

Code:
public void reattachToHibernateSession(MyPersistentObject obj) {
  if (obj.getId() != 0 && !this.getCurrentSession().contains(obj)) {
    try {
      this.getCurrentSession().lock(obj, LockMode.NONE);
    } catch (NonUniqueObjectException e) {
      this.getCurrentSession().evict(obj);
      this.getCurrentSession().flush();
      this.getCurrentSession().lock(obj, LockMode.NONE);
    }
  }
}


I just realized that session.contains(obj) doesn't use obj.equals() to know if the session contains the object, but seems to look at the actual instance. You're right, knowing that, it makes sense that even if the object passed is the same as the one in the hibernate session, it is not always the same instance and evicting an inexistant object doesn't do much. I changed it as follows:

Code:
public void reattachToHibernateSession(MyPersistentObject obj) {
  if (obj != null && obj.getId() != 0) {
    if (!this.getCurrentSession().contains(obj)) {
      Object oldObj = this.getCurrentSession().get(obj.getClass(), obj.getId());
      if (oldObj != null) {
        this.getCurrentSession().evict(oldObj);
      }
      this.getCurrentSession().lock(obj, LockMode.NONE);
    }
  }
}


For now, it seems to work well.

Thanks a lot!


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

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.