Persisting objects

Persisting transient objects may be achieved in various ways. JDBC allows to store and retrieved object values.

Having larger projects these tasks become increasingly tedious. It is thus desired to automate these tasks while still using JDBC™ for the low level transport layer.

The following sections start with a single class hibintro.v1.model.User:

Figure 931. A basic User class.

Todo: Ref/Fig/classUser.fig

Object relational mapping (ORM) denotes the process of mapping instances of classes to relational table data. In our current example we may draw a simple implementation sketch:

Figure 932. Mapping properties to attributes.

Todo: Ref/Fig/mapUser.fig

This is far too simplistic. What about integrity constraints?

Figure 933. Annotating integrity constraints

Todo: Ref/Fig/mapUserIntegrity.fig

We start with the following hibintro.v1.model.User class lacking integrity constraints completely:

package hibintro.v1.model;
	public class User {
	String uid;
	public String getUid() {return uid;}
	public void setUid(String uid) {this.uid = uid;}

	String cname;
	public String getCname() {return cname;}
	public void setCname(String cname) {this.cname = cname;}

	* Hibernate/JPA require a default constructor. It has has to be implemented
	* if any non-default constructor has been defined
	public User() {}

	* @param uid See {@link #getUid()}.
	* @param cname See {@link #getCname()}.
	public User(String uid, String cname) {
	this.uid = uid;
	this.cname = cname;

Persisting objects with Hibernate requires a org.hibernate.Session instance ❶. It happens between the start ❷ and commit ❸ of a transaction being derived from that session:


	public class PersistSingleUser {

	public static void main(String[] args) {
	final org.hibernate.Session session ❶= HibernateUtil.createSessionFactory("hibernate.cfg.xml").openSession();

	final org.hibernate.Transaction transaction = session.beginTransaction();❷

	final hibintro.v1.model.User u = new User("goik", "Martin Goik");;

	transaction.commit(); ❸

Executing the above code yields a runtime exception:

Exception in thread "main" java.lang.ExceptionInInitializerError
	Caused by: org.hibernate.AnnotationException: No identifier specified for entity: myhibernate.intro.model.User
	at myhibernate.intro.util.HibernateUtil.buildConfiguration(
	at myhibernate.intro.util.HibernateUtil.<clinit>(

This runtime error is a little bit cryptic. The missing identifier refers to the absence of a primary key definition already mentioned in Figure 933, “Annotating integrity constraints ”. We define a key by annotating the uid property with a javax.persistence.Id annotation ❶:

package hibintro.v1.model;

	import javax.persistence.Entity;
	import javax.persistence.Id;

	@Entity public class User {...
	@Id ❶
	public String getUid() {
	return uid;
	} ...

The careful reader will have noticed that we've annotated the getter method rather than the property uid itself. Hibernate / JPA can work both ways. Annotating a getter however offers additional support e.g. when logging for debugging purposes is required.

This time we are successful. Since we enabled the logging of SQL statements in Figure 928, “A basic persistence.xml JPA configuration file. ” Hibernate shows us the corresponding INSERT statement:

        (cname, uid) sky
        (?, ?)

Notice the (?,?) part of our log: This indicates the internal usage of JDBCjava.sql.PreparedStatement instances. Hibernate generates the following create table statement:

Figure 934. Database schema mapping instances of hibintro.v1.model.User.
	  cname VARCHAR(255)