Loading Objects by primary key

Having persisted a single hibintro.v1.model.User instance by means of hibintro.v1.run.PersistSingleUser we may now load the database object. The easiest way is based on both the requested object's type ❶ and its primary key value ❷:

Figure 936. Loading a single object by a primary key value.
package hibintro.v1.run;
	  ...
	  public class RetrieveSingleUser {
	  ...
	  final Transaction transaction = session.beginTransaction();

	  final User u = (User) session.load(User.class ❶, "goik" ❷);
	  if (null == u ) {
	  System.out.println("No such user 'goik'");
	  } else {
	  System.out.println("Found user '" + u.getCname() + "'");
	  }
	  transaction.commit();...

This retrieves the expected result. Buried in other log messages we find the following SQL background statement:

...
	INFO: HHH000232: Schema update complete
	Hibernate: 
	select
        user0_.uid as uid0_0_,
        user0_.cname as cname0_0_ 
	from
        User user0_ 
	where
        user0_.uid=?

	Found user 'Martin Goik'

exercise No. 16

Choosing the correct method

Q:

Actually the code in Figure 936, “Loading a single object by a primary key value. ” is not quite correct. Execute it with a non-existing primary key value i.e. goik2. What do you observe? Can you explain that behaviour?

Read the documentation of the org.hibernate.Session.load() method and correct the code snippet.

A:

If there is no corresponding database object we receive a org.hibernate.ObjectNotFoundException :

Hibernate: 
		select
		user0_.uid as uid0_0_,
		user0_.cname as cname0_0_ 
		from
		User user0_ 
		where
		user0_.uid=?
		Exception in thread "main" org.hibernate.ObjectNotFoundException: ❶No row with the given identifier exists: [hibintro.v1.model.User#goik2]
		...
		at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
		at hibintro.v1.model.User_$$_javassist_0.getCname(User_$$_javassist_0.java)
		at hibintro.v1.run.RetrieveSingleUser.main(RetrieveSingleUser.java:35)

Due to ❷ the exception is being triggered by the getCname() call. The documentation of load() tells us that method calls may be delegated to proxy objects which is being implemented by byte code instrumentation. If however no matching database object exists calling the proxy instance yields a org.hibernate.ObjectNotFoundException.

The documentation also tells us to use the corresponding org.hibernate.Session.get(Class,Serializable) method which actually returns null in case a primary key value does not exist:

... final User u = (User) session.get(User.class, "goik2");
		if (null == u ) {
		System.out.println("No such user having key value 'goik2'");
		...