Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does Hibernate's load() method do for non-existing IDs?

Tags:

java

hibernate

I'm a bit confused by the JavaDocs on Session.load:

Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists. This method might return a proxied instance that is initialized on-demand, when a non-identifier method is accessed.

You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.

I understand I'm supposed to use get, but what I don't understand is what is meant with the bit about it initialized on demand when a non-identifier method is used.

For me, if I have a class and use load(MyClass.class, NonExistingID), and then print the output of the getId() on the returned instance, it seems to automatically produce a new instance with NonExistingID every single time. Why is this?

I'm just trying to understand, is getId() a non-identifying method?

like image 630
JustDanyul Avatar asked Sep 14 '11 20:09

JustDanyul


2 Answers

'Non-identifier method' means a method that returns something besides the identifier (as in primary key id) for the object. load gives you a proxy, where the proxy only queries the database once you ask it for something besides the identifier. So getId is an identifier method, Hibernate doesn't query the database for its value (it doesn't have to because you passed it into the load method call).

Found this snippet on the hibernate forums:

An important scenario under which you need to contrast the load and get methods of the Hibernate Session has to do with what happens when you provide a primary key that doesn't actually exist in the database. Well, with the get method, you are simply returned a null object, which is no big deal.

With the load method, there's also no initial problem when you provide an invalid primary key to the method. From what you can tell, Hibernate appears to hand you back a valid, non-null instance of the class in which you are interested. However, the problems start when you actually try to access a property of that instance - that's where you run into trouble.

Remember how I said the load method doesn't hit the database until a property of the bean is requested? Well, if you've provided a primary key that doesn't exist in your database to the load method, when it does go to the database for the first time, it won't be able to find the non-existent, associated record, and your code will cough up big time. In fact, looking up a field based upon a non-existent primary key with the Hibernate Session's load method triggers the following error:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [User#123]

So it sounds like you have used load to get a proxy for a nonexistent object, but since you haven't called any 'nonidentifier methods' on it, you haven't forced the proxy to hit the database and haven't gotten an error.

like image 31
Nathan Hughes Avatar answered Oct 18 '22 03:10

Nathan Hughes


Just to make long story short:

session.load will create proxy object which will be initialized when you call any getter of non-primary key class item.

session.get will return null if the object does not exist and will return the full object if it does exist.

like image 164
danny.lesnik Avatar answered Oct 18 '22 02:10

danny.lesnik