1

I tried below code:

Student s1 = (Student) s.load(Student.class, 5); // this records not there in DB
 try {
    s1.setName("Kaushik1");
} catch (ObjectNotFoundException e) {
    s1 = new Student();
    s1.setId(5);
    s1.setName("trying1");
}
s.saveOrUpdate(s1);

Student s2 = (Student) s.load(Student.class, 5);
try {
    s2.setName("Kaushik2");
} catch (ObjectNotFoundException e) {
    //Why should it throw ObjectNotFoundException now
    s2 = new Student();
    s2.setId(5);
    s2.setName("trying2");
}
s.saveOrUpdate(s2); //Why it throws NonUniqueObjectException

I used load to fetch record from DB with ID#5. Record does not exist. Then I tried calling setter on object, and it threw an exception. Agreed !!

Since the record did not exist I created a new object and called saveOrUpdate(). So now I assume that object with ID#5 is in session cache.

Now I try again to call load() method for ID#5 and call its setter. It throws ObjectNotFoundException again.

Question 1

Why it can not pick record from Session cache ?

When I create new object and try to call saveOrUpdate() it gives a NonUniqueObjectException

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.cts.closr.Student#5]

It threw ObjectNotFoundException and now says "object already associated with the session". Is that not contradictory?

Question 2

Does that mean load() method never checks the session context? It always fetches from DB? Then in such case I must use get() method?

Kaushik Lele
  • 6,439
  • 13
  • 50
  • 76
  • ever tried to flush before loading s2? – Adrian Shum Jan 25 '13 at 06:48
  • open the hibernate log, see the output sql, you will see what really happend for the question 1. for question 2,check this http://stackoverflow.com/questions/7886971/hibernate-load-vs-get – snow8261 Jan 25 '13 at 07:09
  • @snow8261 that link does not anwer my question. Can you highlight the exact lines that you think might answer my question. – Kaushik Lele Jan 25 '13 at 10:18
  • @AdrianShum ... it should work if flush is done, because it will now get the record in DB .... question is, why is not working without flush ? – Kaushik Lele Jan 25 '13 at 10:25

2 Answers2

4

The documentation says:

If the Session throws an exception, including any SQLException, immediately rollback the database transaction, call Session.close() and discard the Session instance. Certain methods of Session will not leave the session in a consistent state. No exception thrown by Hibernate can be treated as recoverable.

So using Session.load(), catching an exception, and continuing using the session is a big no-no. Session.load() must be used when you consider that the object MUST exist in the database, and an exception must be thrown if it doesn't. If you're not sure that the object exists, use Session.get(), test if the returned object is null, and act accordingly.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • I understood that in this case I must use "get" instead of "load". But question is why load did not pick the record from session when it was called second time ? Inside catch for ObjectNotFound, it allowed me to call session.saveOrUpdate(). So session was not closed. – Kaushik Lele Jan 26 '13 at 08:25
  • Sorry , I got your point now. If session throws exception I MUST do rollback, close etc. It will not happen automatically, prograamer should do it. And it is not advisable to continue with same session. Correct ? – Kaushik Lele Jan 26 '13 at 08:34
  • 2
    that is correct. Any further actions performed on the session is essentially unknown behaviour. – drone.ah Jan 26 '13 at 12:40
0

"Now I try again call load() method for ID#5", i believe you type it wrong.

    Student s2 = (Student)s.load(Student.class, 6); 

should it be

    Student s2 = (Student)s.load(Student.class, 5);

?

snow8261
  • 939
  • 2
  • 14
  • 34